run-llama / llama_index

LlamaIndex is a data framework for your LLM applications
https://docs.llamaindex.ai
MIT License
35.41k stars 4.99k forks source link

[Bug]: Error using pydantic response with chat engine #15694

Open Royisaboy opened 2 weeks ago

Royisaboy commented 2 weeks ago

Bug Description

I'm trying to get pydantic response with chat engine but it threw errors. i tried different versions of llamaindex but none of them worked.

Version

0.10.36

Steps to Reproduce

!pip install llama-index-vector-stores-pinecone==0.1.7 pinecone-client==3.2.2 llama-index-embeddings-openai !pip install llama-index==0.10.36

from llama_index.llms.openai import OpenAI as llama_index_openai import openai from llama_index.embeddings.openai import OpenAIEmbedding from pinecone import Pinecone from llama_index.vector_stores.pinecone import PineconeVectorStore from llama_index.core import ( VectorStoreIndex ) from typing import List from pydantic.v1 import BaseModel, Field

class Movie(BaseModel): """Object representing a single movie."""

name: str = Field(..., description="Name of the movie.") year: int = Field(..., description="Year of the movie.")

class Movies(BaseModel): """Object representing a list of movies."""

movies: List[Movie] = Field(..., description="List of movies.")

openai.api_key = "XXX" embed_model = OpenAIEmbedding(model="text-embedding-3-small")

llm = llama_index_openai(temperature=0.1, model="gpt-4o") pc = Pinecone(api_key="XXX") pinecone_index = pc.Index("quick_start") vector_store = PineconeVectorStore(pinecone_index=pinecone_index) loaded_index = VectorStoreIndex.from_vector_store(vector_store=vector_store, embed_model=embed_model) sllm = llm.as_structured_llm(Movies) query_engine = loaded_index.as_chat_engine( chat_mode="context", similarity_top_k=5, llm=sllm ) prompt = ''' Please generate related movies to Titanic ''' response = query_engine.chat(prompt)

Relevant Logs/Tracbacks

ValueError Traceback (most recent call last)
<ipython-input-12-8916b3b995ec> in <cell line: 1>()
----> 1 response = query_engine.chat(prompt)

7 frames
/usr/local/lib/python3.10/dist-packages/llama_index/core/instrumentation/dispatcher.py in wrapper(func, instance, args, kwargs)
 259 )
 260 try:
--> 261 result = func(*args, **kwargs)
 262 except BaseException as e:
 263 self.event(SpanDropEvent(span_id=id_, err_str=str(e)))

/usr/local/lib/python3.10/dist-packages/llama_index/core/callbacks/utils.py in wrapper(self, *args, **kwargs)
 39 callback_manager = cast(CallbackManager, callback_manager)
 40 with callback_manager.as_trace(trace_id):
---> 41 return func(self, *args, **kwargs)
 42 
 43 @functools.wraps(func) # preserve signature, name, etc. of func

/usr/local/lib/python3.10/dist-packages/llama_index/core/chat_engine/condense_plus_context.py in chat(self, message, chat_history)
 287 
 288 # pass the context, system prompt and user message as chat to LLM to generate a response
--> 289 chat_response = self._llm.chat(chat_messages)
 290 assistant_message = chat_response.message
 291 self._memory.put(assistant_message)

/usr/local/lib/python3.10/dist-packages/llama_index/core/instrumentation/dispatcher.py in wrapper(func, instance, args, kwargs)
 259 )
 260 try:
--> 261 result = func(*args, **kwargs)
 262 except BaseException as e:
 263 self.event(SpanDropEvent(span_id=id_, err_str=str(e)))

/usr/local/lib/python3.10/dist-packages/llama_index/core/llms/callbacks.py in wrapped_llm_chat(_self, messages, **kwargs)
 170 )
 171 try:
--> 172 f_return_val = f(_self, messages, **kwargs)
 173 except BaseException as e:
 174 callback_manager.on_event_end(

/usr/local/lib/python3.10/dist-packages/llama_index/core/llms/structured_llm.py in chat(self, messages, **kwargs)
 105 # the messages don't technically have any variables (they are already formatted)
 106 
--> 107 chat_prompt = ChatPromptTemplate(message_templates=_escape_json(messages))
 108 
 109 output = self.llm.structured_predict(

/usr/local/lib/python3.10/dist-packages/llama_index/core/prompts/base.py in __init__(self, message_templates, prompt_type, output_parser, metadata, template_var_mappings, function_mappings, **kwargs)
 247 template_vars = []
 248 for message_template in message_templates:
--> 249 template_vars.extend(get_template_vars(message_template.content or ""))
 250 
 251 super().__init__(

/usr/local/lib/python3.10/dist-packages/llama_index/core/prompts/utils.py in get_template_vars(template_str)
 10 formatter = Formatter()
 11 
---> 12 for _, variable_name, _, _ in formatter.parse(template_str):
 13 if variable_name:
 14 variables.append(variable_name)

ValueError: Single '}' encountered in format string
dosubot[bot] commented 2 weeks ago

@Royisaboy Hey there! I'm here to help you with any bugs, questions, or contributions you might have. Let's get to the bottom of this together.

To resolve the ValueError: Single '}' encountered in format string when using pydantic response with the chat engine in LlamaIndex version 0.10.36, you need to ensure that any braces in your strings are properly escaped. The provided code already includes a utility function _escape_braces that handles this.

You should use the _escape_braces function to escape braces in your chat messages before they are processed. This function is already being used in the _escape_json function, which is applied to the messages in the chat and astream_chat methods.

Here is the relevant part of the code that shows how _escape_braces is used:

def _escape_braces(text: str) -> str:
    """
    Escape braces in text.
    Only captures template variables, skips already escaped braces.
    """

    def replace(match):
        if match.group(0).startswith("{{") and match.group(0).endswith("}}"):
            return match.group(0)  # Already escaped, return as is
        return "{{" + match.group(1) + "}}"

    pattern = r"(?<!\{)\{([^{}]+?)\}(?!\})"
    return re.sub(pattern, replace, text)

def _escape_json(messages: Sequence[ChatMessage]) -> Sequence[ChatMessage]:
    """Escape JSON in messages."""
    new_messages = []
    for message in messages:
        if isinstance(message.content, str):
            escaped_msg = _escape_braces(message.content)
            new_messages.append(
                ChatMessage(
                    role=message.role,
                    content=escaped_msg,
                    additional_kwargs=message.additional_kwargs,
                )
            )
        else:
            new_messages.append(message)
    return new_messages

In the chat method, _escape_json is called to escape the braces in the messages:

@llm_chat_callback()
def chat(self, messages: Sequence[ChatMessage], **kwargs: Any) -> ChatResponse:
    """Chat endpoint for LLM."""
    chat_prompt = ChatPromptTemplate(message_templates=_escape_json(messages))

    output = self.llm.structured_predict(
        output_cls=self.output_cls, prompt=chat_prompt
    )
    return ChatResponse(
        message=ChatMessage(
            role=MessageRole.ASSISTANT, content=output.model_dump_json()
        ),
        raw=output,
    )

Ensure that your messages are passed through _escape_json before being used in the chat engine to avoid the ValueError [1].

To continue talking to Dosu, mention @dosu.

nerdai commented 2 weeks ago

I suspect you are using llama-index-core v0.11.x with lower versions of llama-index-embeddings-openai

We migrated to pydantic v2 in v0.11.x and you'll need to use the latest versions of integration packages as well for compatibility

UPDATE:

My bad, it looks like I have it the other way around. You're core is llama-index-core v0.10.36 but maybe you're using the latest version of llama-index-embeddings-openai

nerdai commented 2 weeks ago

If you install these versions of the packages, then everything should run as expected.

!pip install llama-index-vector-stores-pinecone==0.2.1 llama-index-embeddings-openai==0.2.3
!pip install llama-index==0.11.2
Royisaboy commented 2 weeks ago

KeyError Traceback (most recent call last)

in () ----> 1 response = query_engine.chat(prompt) 10 frames /usr/local/lib/python3.10/dist-packages/llama_index/core/instrumentation/dispatcher.py in wrapper(func, instance, args, kwargs) 259 ) 260 try: --> 261 result = func(*args, **kwargs) 262 except BaseException as e: 263 self.event(SpanDropEvent(span_id=id_, err_str=str(e))) /usr/local/lib/python3.10/dist-packages/llama_index/core/callbacks/utils.py in wrapper(self, *args, **kwargs) 39 callback_manager = cast(CallbackManager, callback_manager) 40 with callback_manager.as_trace(trace_id): ---> 41 return func(self, *args, **kwargs) 42 43 @functools.wraps(func) # preserve signature, name, etc. of func /usr/local/lib/python3.10/dist-packages/llama_index/core/chat_engine/condense_plus_context.py in chat(self, message, chat_history) 287 288 # pass the context, system prompt and user message as chat to LLM to generate a response --> 289 chat_response = self._llm.chat(chat_messages) 290 assistant_message = chat_response.message 291 self._memory.put(assistant_message) /usr/local/lib/python3.10/dist-packages/llama_index/core/instrumentation/dispatcher.py in wrapper(func, instance, args, kwargs) 259 ) 260 try: --> 261 result = func(*args, **kwargs) 262 except BaseException as e: 263 self.event(SpanDropEvent(span_id=id_, err_str=str(e))) /usr/local/lib/python3.10/dist-packages/llama_index/core/llms/callbacks.py in wrapped_llm_chat(_self, messages, **kwargs) 174 ) 175 try: --> 176 f_return_val = f(_self, messages, **kwargs) 177 except BaseException as e: 178 callback_manager.on_event_end( /usr/local/lib/python3.10/dist-packages/llama_index/core/llms/structured_llm.py in chat(self, messages, **kwargs) 107 chat_prompt = ChatPromptTemplate(message_templates=_escape_json(messages)) 108 --> 109 output = self.llm.structured_predict( 110 output_cls=self.output_cls, prompt=chat_prompt 111 ) /usr/local/lib/python3.10/dist-packages/llama_index/core/instrumentation/dispatcher.py in wrapper(func, instance, args, kwargs) 259 ) 260 try: --> 261 result = func(*args, **kwargs) 262 except BaseException as e: 263 self.event(SpanDropEvent(span_id=id_, err_str=str(e))) /usr/local/lib/python3.10/dist-packages/llama_index/core/llms/llm.py in structured_predict(self, output_cls, prompt, **prompt_args) 360 ) 361 --> 362 result = program(**prompt_args) 363 dispatcher.event(LLMStructuredPredictEndEvent(output=result)) 364 return result /usr/local/lib/python3.10/dist-packages/llama_index/core/instrumentation/dispatcher.py in wrapper(func, instance, args, kwargs) 259 ) 260 try: --> 261 result = func(*args, **kwargs) 262 except BaseException as e: 263 self.event(SpanDropEvent(span_id=id_, err_str=str(e))) /usr/local/lib/python3.10/dist-packages/llama_index/core/program/function_program.py in __call__(self, llm_kwargs, *args, **kwargs) 193 tool = _get_function_tool(self._output_cls) 194 --> 195 messages = self._prompt.format_messages(llm=self._llm, **kwargs) 196 messages = self._llm._extend_messages(messages) 197 /usr/local/lib/python3.10/dist-packages/llama_index/core/prompts/base.py in format_messages(***failed resolving arguments***) 312 313 # if there's mappings specified, make sure those are used --> 314 content = content_template.format(**relevant_kwargs) 315 316 message: ChatMessage = message_template.model_copy() KeyError: '\n "project_name"' project_name: str = Field(..., description="The project name.") project_name is a field in our data model
nerdai commented 2 weeks ago

Sorry, could we also import both BaseModel and Field from our pydantic bridge:

from llama_index.core.bridge.pydantic import BaseModel, Field
Royisaboy commented 2 weeks ago

still same error

nerdai commented 2 weeks ago

Could you try this and see if you get the same errors? I was able to run through this code with no problem. It looks like there's an issue with the output from the llm from your traceback, where there is an extra "\n " in the project_name key.

from llama_index.core.bridge.pydantic import BaseModel, Field
from llama_index.core.llms import ChatMessage
from typing import List

class ExecSummary(BaseModel):
    """Data model for a executive summary for a project."""

    project_name: str = Field(..., description="The project name.")
    summary: str = Field(..., description="A high level summary of the project progress. Please limit it to max 100 characters.")
    risk_description: str = Field(..., description="A risk description that highlights the most outstanding risk. Please limit it to max 15 characters")
    risk_level: str = Field(..., description="A risk level that is choosen from 'high', 'medium' and 'low'.")

class AllExecSummary(BaseModel):
    """Data model for a list of executive summaries for all projects."""
    summaries: List[ExecSummary] = Field(..., description="A list of executive summaries.")

sllm = llm.as_structured_llm(output_cls=AllExecSummary)
input_msg = ChatMessage.from_str("Generate an all exec summary.")

output = sllm.chat([input_msg])
output_obj = output.raw
print(output_obj)
Royisaboy commented 2 weeks ago

this one works for me (it also worked before) but why it doesn't work for chat engine?

nerdai commented 2 weeks ago

I suspect there's something not right with the LLM output of the chat engine which breaks things when trying to construct the Pydantic BaseModel. Doing some more digging.

nerdai commented 2 weeks ago

Would you be able to share a bit more code for me to replicate the error?

Royisaboy commented 2 weeks ago

openai.api_key = "XXX" embed_model = OpenAIEmbedding(model="text-embedding-3-small")

llm = llama_index_openai(temperature=0.1, model="gpt-4o") pc = Pinecone(api_key="XXX") pinecone_index = pc.Index("get_started") vector_store = PineconeVectorStore(pinecone_index=pinecone_index) loaded_index = VectorStoreIndex.from_vector_store(vector_store=vector_store, embed_model=embed_model) sllm = llm.as_structured_llm(AllExecSummary) query_engine = loaded_index.as_chat_engine( chat_mode="context", similarity_top_k=5, llm=sllm ) prompt = ''' Provide executive summaries for project amber and project lina from last two weeks. The response of this instruction must be in JSON format. ''' response = query_engine.chat(prompt)

nerdai commented 2 weeks ago

hmmm this seems to work for me rather than producing the error from before (shared again below)

KeyError: '\n "project_name"'
project_name: str = Field(..., description="The project name.")

The other thing of note tho is that my response.response is not a Pydantic object but rather is a str type (doesn't look like we support pydantic objects as outputs with chat_engine.chat().

Royisaboy commented 2 weeks ago

can you share your full working codes?

nerdai commented 2 weeks ago

%pip install llama-index-vector-stores-pinecone==0.2.1 llama-index-embeddings-openai==0.2.3 -q

import json
from llama_index.core import VectorStoreIndex
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.vector_stores.pinecone import PineconeVectorStore
from pinecone import Pinecone
from llama_index.core.bridge.pydantic import BaseModel, Field
from llama_index.core.llms import ChatMessage
from typing import List

class ExecSummary(BaseModel):
    """Data model for a executive summary for a project."""

    project_name: str = Field(..., description="The project name.")
    summary: str = Field(..., description="A high level summary of the project progress. Please limit it to max 100 characters.")
    risk_description: str = Field(..., description="A risk description that highlights the most outstanding risk. Please limit it to max 15 characters")
    risk_level: str = Field(..., description="A risk level that is choosen from 'high', 'medium' and 'low'.")

class AllExecSummary(BaseModel):
    """Data model for a list of executive summaries for all projects."""
    summaries: List[ExecSummary] = Field(..., description="A list of executive summaries.")

pinecone_api_key = "..."
embed_model = OpenAIEmbedding(model="text-embedding-3-small")
llm = OpenAI(temperature=0.1, model="gpt-4o")
pc = Pinecone(api_key=pinecone_api_key)
pinecone_index = pc.Index("quickstart")
vector_store = PineconeVectorStore(pinecone_index=pinecone_index)
loaded_index = VectorStoreIndex.from_vector_store(vector_store=vector_store, embed_model=embed_model)

sllm = llm.as_structured_llm(output_cls=AllExecSummary)
chat_engine = loaded_index.as_chat_engine(
    chat_mode="context",
    similarity_top_k=5,
    llm=sllm
)
prompt = '''
Provide executive summaries for project amber and project lina from last two weeks.
You must call the tool to generate the formatted output.
The response of this instruction must be in JSON format.
'''

response = chat_engine.chat(prompt)
obj = AllExecSummary(**json.loads(response.response))
Royisaboy commented 2 weeks ago

it cannot be reproduced. for example, openai is not being imported. but after i get all libraries ready i saw same issue. can you show a full google colab script?

nerdai commented 2 weeks ago

Hmmm. I don't really need to import openai directly here. The script above should work completely, though it does require two api keys:

I can share a Google collab version of this shortly.

nerdai commented 2 weeks ago

@Royisaboy: here is a google colab version of the code snippet I shared earlier.

Royisaboy commented 2 weeks ago

same code producing error when i am trying to run it on my end:


KeyError Traceback (most recent call last) in <cell line: 1>() ----> 1 response = chat_engine.chat(prompt) 2 obj = AllExecSummary(**json.loads(response.response))

10 frames /usr/local/lib/python3.10/dist-packages/llama_index/core/instrumentation/dispatcher.py in wrapper(func, instance, args, kwargs) 259 ) 260 try: --> 261 result = func(*args, **kwargs) 262 except BaseException as e: 263 self.event(SpanDropEvent(spanid=id, err_str=str(e)))

/usr/local/lib/python3.10/dist-packages/llama_index/core/callbacks/utils.py in wrapper(self, *args, *kwargs) 39 callback_manager = cast(CallbackManager, callback_manager) 40 with callback_manager.as_trace(trace_id): ---> 41 return func(self, args, **kwargs) 42 43 @functools.wraps(func) # preserve signature, name, etc. of func

/usr/local/lib/python3.10/dist-packages/llama_index/core/chat_engine/context.py in chat(self, message, chat_history, prev_chunks) 184 initial_token_count=prefix_messages_token_count 185 ) --> 186 chat_response = self._llm.chat(all_messages) 187 ai_message = chat_response.message 188 self._memory.put(ai_message)

/usr/local/lib/python3.10/dist-packages/llama_index/core/instrumentation/dispatcher.py in wrapper(func, instance, args, kwargs) 259 ) 260 try: --> 261 result = func(*args, **kwargs) 262 except BaseException as e: 263 self.event(SpanDropEvent(spanid=id, err_str=str(e)))

/usr/local/lib/python3.10/dist-packages/llama_index/core/llms/callbacks.py in wrapped_llm_chat(_self, messages, kwargs) 174 ) 175 try: --> 176 f_return_val = f(_self, messages, kwargs) 177 except BaseException as e: 178 callback_manager.on_event_end(

/usr/local/lib/python3.10/dist-packages/llama_index/core/llms/structured_llm.py in chat(self, messages, **kwargs) 107 chat_prompt = ChatPromptTemplate(message_templates=_escape_json(messages)) 108 --> 109 output = self.llm.structured_predict( 110 output_cls=self.output_cls, prompt=chat_prompt 111 )

/usr/local/lib/python3.10/dist-packages/llama_index/core/instrumentation/dispatcher.py in wrapper(func, instance, args, kwargs) 259 ) 260 try: --> 261 result = func(*args, **kwargs) 262 except BaseException as e: 263 self.event(SpanDropEvent(spanid=id, err_str=str(e)))

/usr/local/lib/python3.10/dist-packages/llama_index/core/llms/llm.py in structured_predict(self, output_cls, prompt, prompt_args) 360 ) 361 --> 362 result = program(prompt_args) 363 dispatcher.event(LLMStructuredPredictEndEvent(output=result)) 364 return result

/usr/local/lib/python3.10/dist-packages/llama_index/core/instrumentation/dispatcher.py in wrapper(func, instance, args, kwargs) 259 ) 260 try: --> 261 result = func(*args, **kwargs) 262 except BaseException as e: 263 self.event(SpanDropEvent(spanid=id, err_str=str(e)))

/usr/local/lib/python3.10/dist-packages/llama_index/core/program/function_program.py in call(self, llm_kwargs, *args, kwargs) 193 tool = _get_function_tool(self._output_cls) 194 --> 195 messages = self._prompt.format_messages(llm=self._llm, kwargs) 196 messages = self._llm._extend_messages(messages) 197

/usr/local/lib/python3.10/dist-packages/llama_index/core/prompts/base.py in format_messages(failed resolving arguments) 312 313 # if there's mappings specified, make sure those are used --> 314 content = content_template.format(**relevant_kwargs) 315 316 message: ChatMessage = message_template.model_copy()

KeyError: '\n "project_name"'

Royisaboy commented 2 weeks ago

are you using python3.10?

Hkllopp commented 4 days ago

Hi !

I encountered the same issue. I tried using llama-index-agent-openai==0.3.1 and 0.3.2 (latest version). I'm using in-memory storage so it probably has nothing to do with the pinecone db rather than the openAI package.

import json
import os
from typing import List

from llama_index.core import Settings, SimpleDirectoryReader, VectorStoreIndex
from llama_index.core.bridge.pydantic import BaseModel, Field
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.llms.openai import OpenAI

OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")

class Movie(BaseModel):
    name: str = Field(..., alias="name")
    length: int = Field(..., alias="length")

class MovieList(BaseModel):
    name: str = Field(..., alias="name")
    movies: List[Movie] = Field(..., alias="movies")

Settings.embed_model = OpenAIEmbedding()
Settings.llm = OpenAI("gpt-4", temperature=0).as_structured_llm(
    output_cls=MovieList
)

movies_lists = [
    {
        "name": "Horror movies list",
        "movies": [
            {"name": "The Conjuring", "length": 112},
            {"name": "The Exorcist", "length": 122},
            {"name": "The Shining", "length": 146},
        ],
    },
    {
        "name": "Sci-fi movies list",
        "movies": [
            {"name": "Star Wars", "length": 121},
            {"name": "Interstellar", "length": 169},
            {"name": "The Matrix", "length": 136},
        ],
    },
]

# Save as text file
with open("movie_list.txt", "w") as f:
    f.write(json.dumps(movies_lists))

# load only the file
documents = SimpleDirectoryReader(input_files=["movie_list.txt"]).load_data()
index = VectorStoreIndex.from_documents(
    documents,
)

query_engine = index.as_query_engine(response_mode="refine", verbose=True)
response = query_engine.query(
    "Give me the horror movies lists and their associated movies"
)

# Print the response to debug
print(f"Response: {response}")

Output

python scripts/demo/testError.py 
Traceback (most recent call last):
  File "/home/ubuntu/Documents/.../scripts/demo/testError.py", line 60, in <module>
    response = query_engine.query(
               ^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/core/instrumentation/dispatcher.py", line 265, in wrapper
    result = func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/core/base/base_query_engine.py", line 52, in query
    query_result = self._query(str_or_query_bundle)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/core/instrumentation/dispatcher.py", line 265, in wrapper
    result = func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/core/query_engine/retriever_query_engine.py", line 176, in _query
    response = self._response_synthesizer.synthesize(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/core/instrumentation/dispatcher.py", line 265, in wrapper
    result = func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/core/response_synthesizers/base.py", line 241, in synthesize
    response_str = self.get_response(
                   ^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/core/instrumentation/dispatcher.py", line 265, in wrapper
    result = func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/core/response_synthesizers/refine.py", line 177, in get_response
    response = self._give_response_single(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/core/response_synthesizers/refine.py", line 234, in _give_response_single
    program(
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/core/instrumentation/dispatcher.py", line 265, in wrapper
    result = func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/core/response_synthesizers/refine.py", line 84, in __call__
    answer = self._llm.predict(
             ^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/core/instrumentation/dispatcher.py", line 265, in wrapper
    result = func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/core/llms/llm.py", line 578, in predict
    chat_response = self.chat(messages)
                    ^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/core/instrumentation/dispatcher.py", line 265, in wrapper
    result = func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/core/llms/callbacks.py", line 173, in wrapped_llm_chat
    f_return_val = f(_self, messages, **kwargs)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/core/llms/structured_llm.py", line 109, in chat
    output = self.llm.structured_predict(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/core/instrumentation/dispatcher.py", line 265, in wrapper
    result = func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/llms/openai/base.py", line 963, in structured_predict
    return super().structured_predict(*args, llm_kwargs=llm_kwargs, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/core/instrumentation/dispatcher.py", line 265, in wrapper
    result = func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/core/llms/llm.py", line 363, in structured_predict
    result = program(llm_kwargs=llm_kwargs, **prompt_args)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/core/instrumentation/dispatcher.py", line 265, in wrapper
    result = func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/core/program/function_program.py", line 199, in __call__
    messages = self._prompt.format_messages(llm=self._llm, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Documents/.../venv/lib/python3.12/site-packages/llama_index/core/prompts/base.py", line 314, in format_messages
    content = content_template.format(**relevant_kwargs)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
KeyError: '"name"'