run-llama / llama_index

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

[Bug]: ElasticSearch Vector Store : Timeout context manager should be used inside a task #14428

Open FlorentGrenier opened 6 days ago

FlorentGrenier commented 6 days ago

Bug Description

I'm developing a chatbot, and on a second request sent the bug appears

bug_llama_index

I don't know if I should post this here or open a problem with the Python Elasticsearch library.

Version

0.10.50

Steps to Reproduce

Send a second query to the RetrieverQueryEngine, built from a VectorIndexRetriever, a VectorStoreIndex and an ElasticSearchVectorStore.

Relevant Logs/Tracbacks

Traceback (most recent call last):
  File "C:\Users\fgr\AppData\Local\anaconda3\envs\llama-index\Lib\site-packages\streamlit\runtime\scriptrunner\script_runner.py", line 589, in _run_script
    exec(code, module.__dict__)
  File "C:\data\git\AthenIA\streamlit_app.py", line 52, in <module>
    response = response_generator.chat(user_query=prompt)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\data\git\AthenIA\src\components\response_synthesis.py", line 84, in chat
    content = self.build_context_prompt(self.retriever(user_query=user_query))
                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\data\git\AthenIA\src\components\response_synthesis.py", line 61, in retriever
    retrieved_nodes = retriever.retrieve(user_query)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\fgr\AppData\Local\anaconda3\envs\llama-index\Lib\site-packages\llama_index\core\instrumentation\dispatcher.py", line 230, in wrapper
    result = func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\fgr\AppData\Local\anaconda3\envs\llama-index\Lib\site-packages\llama_index\core\base\base_retriever.py", line 243, in retrieve
    nodes = self._retrieve(query_bundle)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\fgr\AppData\Local\anaconda3\envs\llama-index\Lib\site-packages\llama_index\core\instrumentation\dispatcher.py", line 230, in wrapper
    result = func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\fgr\AppData\Local\anaconda3\envs\llama-index\Lib\site-packages\llama_index\core\indices\vector_store\retrievers\retriever.py", line 101, in _retrieve
    return self._get_nodes_with_embeddings(query_bundle)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\fgr\AppData\Local\anaconda3\envs\llama-index\Lib\site-packages\llama_index\core\indices\vector_store\retrievers\retriever.py", line 177, in _get_nodes_with_embeddings
    query_result = self._vector_store.query(query, **self._kwargs)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\fgr\AppData\Local\anaconda3\envs\llama-index\Lib\site-packages\llama_index\vector_stores\elasticsearch\base.py", line 412, in query
    return asyncio.get_event_loop().run_until_complete(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\fgr\AppData\Local\anaconda3\envs\llama-index\Lib\site-packages\nest_asyncio.py", line 98, in run_until_complete
    return f.result()
           ^^^^^^^^^^
  File "C:\Users\fgr\AppData\Local\anaconda3\envs\llama-index\Lib\asyncio\futures.py", line 203, in result     
    raise self._exception.with_traceback(self._exception_tb)
  File "C:\Users\fgr\AppData\Local\anaconda3\envs\llama-index\Lib\asyncio\tasks.py", line 314, in __step_run_and_handle_result
    result = coro.send(None)
             ^^^^^^^^^^^^^^^
  File "C:\Users\fgr\AppData\Local\anaconda3\envs\llama-index\Lib\site-packages\llama_index\vector_stores\elasticsearch\base.py", line 452, in aquery
    hits = await self._store.search(
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\fgr\AppData\Local\anaconda3\envs\llama-index\Lib\site-packages\elasticsearch\helpers\vectorstore\_async\vectorstore.py", line 277, in search
    response = await self.client.search(
               ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\fgr\AppData\Local\anaconda3\envs\llama-index\Lib\site-packages\elasticsearch\_async\client\__init__.py", line 4121, in search
    return await self.perform_request(  # type: ignore[return-value]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\fgr\AppData\Local\anaconda3\envs\llama-index\Lib\site-packages\elasticsearch\_async\client\_base.py", line 271, in perform_request
    response = await self._perform_request(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\fgr\AppData\Local\anaconda3\envs\llama-index\Lib\site-packages\elasticsearch\_async\client\_base.py", line 316, in _perform_request
    meta, resp_body = await self.transport.perform_request(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\fgr\AppData\Local\anaconda3\envs\llama-index\Lib\site-packages\elastic_transport\_async_transport.py", line 264, in perform_request
    resp = await node.perform_request(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\fgr\AppData\Local\anaconda3\envs\llama-index\Lib\site-packages\elastic_transport\_node\_http_aiohttp.py", line 179, in perform_request
    async with self.session.request(
  File "C:\Users\fgr\AppData\Local\anaconda3\envs\llama-index\Lib\site-packages\aiohttp\client.py", line 1197, in __aenter__
    self._resp = await self._coro
                 ^^^^^^^^^^^^^^^^
  File "C:\Users\fgr\AppData\Local\anaconda3\envs\llama-index\Lib\site-packages\aiohttp\client.py", line 507, in _request
    with timer:
  File "C:\Users\fgr\AppData\Local\anaconda3\envs\llama-index\Lib\site-packages\aiohttp\helpers.py", line 715, in __enter__
    raise RuntimeError(
RuntimeError: Timeout context manager should be used inside a task
dosubot[bot] commented 6 days ago

Hello @FlorentGrenier! I'm here to help you with any bugs, questions, or contributions you have. Let's work together to solve this issue.

To resolve the "Timeout context manager should be used inside a task" error that occurs on the second request sent to the RetrieverQueryEngine in your chatbot application, ensure that all asynchronous operations are properly awaited within an asynchronous context. This error typically arises when an asynchronous operation is attempted outside of an asynchronous context.

Here is an example of how you can properly use the aresponse_gen_from_query_engine function within an asynchronous function:

import asyncio
from llama_index.core.chat_engine.utils import aresponse_gen_from_query_engine

async def handle_request(response_gen):
    async for response in aresponse_gen_from_query_engine(response_gen):
        # Process the response
        print(response.message.content)

# Example usage
async def main():
    # Assuming `response_gen` is an asynchronous generator obtained from `RetrieverQueryEngine`
    response_gen = get_response_gen_from_retriever_query_engine()  # Replace with actual call
    await handle_request(response_gen)

# Run the main function
asyncio.run(main())

Ensure that get_response_gen_from_retriever_query_engine is replaced with the actual call to your RetrieverQueryEngine that returns an asynchronous generator. This way, the aresponse_gen_from_query_engine function is used within an asynchronous context, preventing the "Timeout context manager should be used inside a task" error.

Additionally, if you are using the CondenseQuestionChatEngine class, make sure that the achat and astream_chat methods are properly awaited and used within an asynchronous context. Here is an example of how you can use these methods:

from llama_index.legacy.chat_engine.condense_question import CondenseQuestionChatEngine

async def main():
    # Initialize your CondenseQuestionChatEngine with appropriate parameters
    chat_engine = CondenseQuestionChatEngine.from_defaults(query_engine, condense_question_prompt, memory, llm)

    # Use the achat method for asynchronous chat
    response = await chat_engine.achat("Your message here")
    print(response.response)

    # Use the astream_chat method for asynchronous streaming chat
    streaming_response = await chat_engine.astream_chat("Your message here")
    async for message in streaming_response.chat_stream:
        print(message.content)

# Run the main function
asyncio.run(main())

It's important to note that the RetrySourceQueryEngine class does not support asynchronous querying directly, as indicated by the async def _aquery method returning the result of the synchronous _query method. Therefore, ensure that you are not attempting to use asynchronous operations with RetrySourceQueryEngine directly. Instead, use the synchronous _query method within an appropriate context.

By ensuring that all asynchronous operations are properly awaited within an asynchronous context, and by using the correct methods for synchronous operations, you can avoid the "Timeout context manager should be used inside a task" error [1][2][3][4].

To continue talking to Dosu, mention @dosu.

logan-markewich commented 6 days ago

I'm like 90% sure this is an issue in the elastic search library 🤔