You are an python expert. In the below code - the input doesn't seem to be going through - 
import openai
from typing_extensions import TypedDict  # Use this for Python < 3.12
from typing import List, Optional
from pydantic import BaseModel, Field
from io import BytesIO
from PIL import Image
from IPython.display import display
import json

# Import necessary classes from LangChain
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.schema import HumanMessage, SystemMessage

# Set your OpenAI API key
openai.api_key = "<TRUFFLEHOG_REDACTED_OPENAI>"  # Replace with your actual OpenAI API key

# Define the structure for BP fields
class OutputField(TypedDict):
    name: str
    description: str
    type: str
    source: str
    required: bool

class BPState(TypedDict):
    goal: str
    output_fields: List[OutputField]
    examples: List[str]
    improved_goal: str
    grokked_output_fields: List[OutputField]
    generated_examples: List[str]
    chosen_prompt: str

# Define structured models for OpenAI's LLM function calls
class ImprovedGoal(BaseModel):
    """Structured output for improved goal."""
    improved_goal: str = Field(description="The improved or rephrased version of the user's goal.")

class GrokkedOutputFields(BaseModel):
    """Structured output for grokked output fields."""
    grokked_output_fields: List[OutputField] = Field(description="The enhanced output fields list.")

class GeneratedExamples(BaseModel):
    """Structured output for generated examples."""
    examples: List[str] = Field(description="Generated examples based on the goal and output fields.")

class ChosenPrompt(BaseModel):
    """Structured output for chosen prompt."""
    chosen_prompt: str = Field(description="The most complete prompt chosen for inference.")

# Initialize the OpenAI LLM via LangChain
llm = ChatOpenAI(model_name="gpt-4", temperature=0)  # Corrected model name

# 1. Enhance Goal
def enhance_goal(state: BPState) -> BPState:
    """Improve or rephrase the goal using OpenAI API."""
    goal_system = "You are a goal improvement agent. Improve the following goal."
    goal_prompt = ChatPromptTemplate.from_messages(
        [
            SystemMessage(content=goal_system),
            HumanMessage(content="Goal: {goal}")
        ]
    )
    # Format the prompt with the current goal
    formatted_prompt = goal_prompt.format_messages(goal=state["goal"])
    
    # Get the response from the LLM
    response = llm(formatted_prompt)
    
    # Extract improved goal (Assuming the LLM returns the improved goal directly)
    improved_goal = response.content.strip()
    
    # Update the state with the improved goal
    state["improved_goal"] = improved_goal
    state["goal"] = improved_goal  # Replace the original goal
    return state

# 2. Enhance Output Fields
def enhance_output_fields(state: BPState) -> BPState:
    """Enhance output fields using OpenAI API."""
    grok_system = "You are a field augmentation agent. Suggest output fields based on the goal."
    grok_prompt = ChatPromptTemplate.from_messages(
        [
            SystemMessage(content=grok_system),
            HumanMessage(content="Goal: {goal}")
        ]
    )
    # Format the prompt with the goal
    formatted_prompt = grok_prompt.format_messages(goal=state["goal"])
    
    # Get the response from the LLM
    response = llm(formatted_prompt)
    
    # Parse the response into OutputField structures
    try:
        grokked_output_fields = json.loads(response.content)
    except json.JSONDecodeError:
        print("Error parsing grokked output fields. Retaining original fields.")
        grokked_output_fields = state["output_fields"]
    
    # Update the state with grokked output fields
    state["grokked_output_fields"] = grokked_output_fields
    state["output_fields"] = grokked_output_fields  # Replace original fields
    return state

# 3. Enhance Examples
def enhance_examples(state: BPState) -> BPState:
    """Enhance examples using OpenAI API."""
    examples_system = "You are an example generation agent. Refine the following examples for clarity and completeness."
    examples_prompt = ChatPromptTemplate.from_messages(
        [
            SystemMessage(content=examples_system),
            HumanMessage(content="Examples: {examples}")
        ]
    )
    # Convert examples to a readable format
    examples_str = "\n".join(state["examples"])
    
    # Format the prompt with current examples
    formatted_prompt = examples_prompt.format_messages(examples=examples_str)
    
    # Get the response from the LLM
    response = llm(formatted_prompt)
    
    # Assuming the LLM returns refined examples separated by newlines
    refined_examples = response.content.strip().split('\n')
    
    # Update the state with refined examples
    state["generated_examples"] = refined_examples
    state["examples"] = refined_examples  # Replace original examples
    return state

# 4. Generate Candidate Prompts
def generate_candidate_prompts(state: BPState) -> List[str]:
    """Generate three candidate prompts using structured output."""
    prompt_system = "You are a prompt generator. Create a complete prompt based on the following goal, output fields, and examples."
    prompt_template = ChatPromptTemplate.from_messages(
        [
            SystemMessage(content=prompt_system),
            HumanMessage(content="Goal: {goal}, Output Fields: {output_fields}, Examples: {examples}")
        ]
    )
    
    candidates = []
    
    # Convert output_fields and examples to readable formats
    output_fields_str = json.dumps(state["output_fields"], indent=2)
    examples_str = "\n".join(state["examples"])
    
    for _ in range(3):  # Generate 3 candidate prompts
        formatted_prompt = prompt_template.format_messages(
            goal=state["goal"],
            output_fields=output_fields_str,
            examples=examples_str
        )
        response = llm(formatted_prompt)
        chosen_prompt = response.content.strip()
        candidates.append(chosen_prompt)
    
    return candidates

# 5. Evaluate Prompts Using G-Eval
def geval_evaluate(prompt: str) -> float:
    """
    Evaluate the prompt using G-Eval and return a completeness score.
    Higher scores indicate more complete prompts.
    
    Placeholder implementation:
    Replace this with actual G-Eval integration.
    """
    # Example placeholder: Use OpenAI to simulate G-Eval behavior
    evaluator_system = "You are a prompt evaluator. Score the completeness of the following prompt on a scale of 1 to 10."
    evaluator_prompt = ChatPromptTemplate.from_messages(
        [
            SystemMessage(content=evaluator_system),
            HumanMessage(content=f"Prompt: {prompt}")
        ]
    )
    formatted_prompt = evaluator_prompt.format_messages()
    response = llm(formatted_prompt)
    try:
        score = float(response.content.strip())
    except ValueError:
        score = 0.0  # Default score if parsing fails
    return score

def evaluate_prompts_with_geval(candidates: List[str]) -> str:
    """Select the best prompt using G-Eval for evaluation."""
    prompt_scores = {}
    for prompt in candidates:
        score = geval_evaluate(prompt)
        prompt_scores[prompt] = score
        print(f"Prompt Score: {score} for Prompt: {prompt[:60]}...")  # Truncated for readability
    
    # Select the prompt with the highest score
    best_prompt = max(prompt_scores, key=prompt_scores.get)
    return best_prompt

# Overall Workflow with Selective Enhancements and G-Eval
def run_blueprint_workflow(
    goal: str,
    output_fields: List[OutputField],
    examples: List[str],
    enhance_goal_flag: bool = False,
    enhance_output_fields_flag: bool = False,
    enhance_examples_flag: bool = False
) -> str:
    """Run the BP workflow with optional enhancements and return the chosen prompt."""
    # Initial state with user inputs
    state: BPState = {
        "goal": goal,
        "output_fields": output_fields,
        "examples": examples,
        "improved_goal": "",
        "grokked_output_fields": [],
        "generated_examples": [],
        "chosen_prompt": ""
    }
    
    # Step 1: Conditionally Enhance the Goal
    if enhance_goal_flag:
        state = enhance_goal(state)
    
    # Step 2: Conditionally Enhance Output Fields
    if enhance_output_fields_flag:
        state = enhance_output_fields(state)
    
    # Step 3: Conditionally Enhance Examples
    if enhance_examples_flag:
        state = enhance_examples(state)
    
    # Step 4: Generate Candidate Prompts
    candidates = generate_candidate_prompts(state)
    
    # Step 5: Evaluate and choose the best prompt using G-Eval
    state["chosen_prompt"] = evaluate_prompts_with_geval(candidates)
    
    return state["chosen_prompt"]

# Example Input Data
goal_input = "Create an AI agent that helps with task scheduling based on user availability."
output_fields_input = [
    {
        "name": "task_name",
        "description": "The name of the task to schedule.",
        "type": "string",
        "source": "user input",
        "required": True
    },
    {
        "name": "scheduled_time",
        "description": "The time at which the task is scheduled.",
        "type": "datetime",
        "source": "calendar",
        "required": True
    }
]
examples_input = [
    "Input: Schedule a meeting for tomorrow at 10 AM. Output: {'task_name': 'meeting', 'scheduled_time': '2023-10-23T10:00:00'}.",
    "Input: Set a reminder for next Monday. Output: {'task_name': 'reminder', 'scheduled_time': '2023-10-30T09:00:00'}."
]

# Example User Choices for Enhancement
user_wants_to_enhance_goal = True
user_wants_to_enhance_output_fields = False
user_wants_to_enhance_examples = True

# Running the workflow with user-selected enhancements
chosen_prompt = run_blueprint_workflow(
    goal=goal_input,
    output_fields=output_fields_input,
    examples=examples_input,
    enhance_goal_flag=user_wants_to_enhance_goal,
    enhance_output_fields_flag=user_wants_to_enhance_output_fields,
    enhance_examples_flag=user_wants_to_enhance_examples
)

# Output the chosen prompt
print("Chosen Prompt for Inference:")
print(chosen_prompt)