Spaces:
Running
Running
| """ | |
| Finalyzer Agent: Creates final polished solution with clear output. | |
| This agent runs when the verifier confirms the plan is sufficient. | |
| It generates a final version of the code with improved formatting and output. | |
| """ | |
| from langchain_core.messages import AIMessage | |
| from ..utils.code_execution import execute_code_safely | |
| from ..utils.formatters import extract_code, format_data_descriptions, gemini_text | |
| from ..utils.state import DSStarState | |
| def finalyzer_node(state: DSStarState) -> dict: | |
| """ | |
| Finalyzer Agent Node: Creates final polished solution. | |
| Takes the working code and creates a final version with: | |
| - Clear answer to the original question | |
| - Proper output formatting | |
| - Self-contained executable code | |
| Args: | |
| state: Current DSStarState | |
| Returns: | |
| Dictionary with updated state fields: | |
| - current_code: Final polished code | |
| - execution_result: Final execution output | |
| - messages: Agent communication messages | |
| - next: "__end__" (workflow complete) | |
| """ | |
| print("=" * 60) | |
| print("FINALYZER AGENT STARTING...") | |
| print("=" * 60) | |
| data_context = format_data_descriptions(state["data_descriptions"]) | |
| prompt = f"""You are an expert data analyst creating final solutions. | |
| Original Question: {state["query"]} | |
| Available Data: | |
| {data_context} | |
| Working Code: | |
| {state["current_code"]} | |
| Execution Result: | |
| {state["execution_result"]} | |
| Task: Create a final version of the code that: | |
| 1. Clearly prints the answer to the question | |
| 2. Includes proper formatting of the output | |
| 3. Is self-contained and executable | |
| 4. Has clear print statements | |
| Provide ONLY the final Python code in a markdown code block.""" | |
| try: | |
| # Get LLM response | |
| response = state["llm"].invoke(prompt) | |
| # Handle different response formats | |
| if hasattr(response, "content") and isinstance(response.content, list): | |
| response_text = gemini_text(response) | |
| elif hasattr(response, "content"): | |
| response_text = response.content | |
| else: | |
| response_text = str(response) | |
| final_code = extract_code(response_text) | |
| print("\nFinal Code Generated:") | |
| print("-" * 60) | |
| print(final_code[:300] + "..." if len(final_code) > 300 else final_code) | |
| print("-" * 60) | |
| # Execute final code | |
| print("\nExecuting final code...") | |
| success, stdout, stderr = execute_code_safely(final_code) | |
| if success: | |
| final_result = stdout | |
| print("\n✓ Final execution successful") | |
| else: | |
| # If final execution fails, use previous result | |
| print("\n⚠ Final execution failed, using previous result") | |
| final_result = state["execution_result"] | |
| print("\nFinal Result:") | |
| print("-" * 60) | |
| print(final_result[:300] + "..." if len(final_result) > 300 else final_result) | |
| print("-" * 60) | |
| print("=" * 60) | |
| print("SOLUTION COMPLETE ✓") | |
| print("=" * 60) | |
| return { | |
| "current_code": final_code, | |
| "execution_result": final_result, | |
| "messages": [AIMessage(content="Solution finalized")], | |
| "next": "__end__", | |
| } | |
| except Exception as e: | |
| # On error, return current state | |
| print(f"\n✗ Finalyzer error: {str(e)}") | |
| print("Using current solution as final") | |
| return { | |
| "messages": [ | |
| AIMessage(content=f"Finalyzer error: {str(e)}, using current solution") | |
| ], | |
| "next": "__end__", | |
| } | |
| # Standalone test function | |
| def test_finalyzer( | |
| llm, query: str, data_descriptions: dict, current_code: str, execution_result: str | |
| ): | |
| """ | |
| Test the finalyzer agent independently. | |
| Args: | |
| llm: LLM instance | |
| query: User query | |
| data_descriptions: Dict of filename -> description | |
| current_code: Working code to finalize | |
| execution_result: Current execution result | |
| Returns: | |
| Dictionary with finalyzer results | |
| """ | |
| # Create minimal test state | |
| test_state = { | |
| "llm": llm, | |
| "query": query, | |
| "data_descriptions": data_descriptions, | |
| "plan": [], | |
| "current_code": current_code, | |
| "execution_result": execution_result, | |
| "is_sufficient": True, | |
| "router_decision": "", | |
| "iteration": 0, | |
| "max_iterations": 20, | |
| "messages": [], | |
| "next": "finalyzer", | |
| } | |
| result = finalyzer_node(test_state) | |
| print("\n" + "=" * 60) | |
| print("FINALYZER TEST RESULTS") | |
| print("=" * 60) | |
| print("Final Code:") | |
| print(result.get("current_code", "No code")) | |
| print("\nFinal Result:") | |
| print(result.get("execution_result", "No result")) | |
| return result | |