Repository: truera/trulens
Issue:  Error Executing llama_index_quickstart.ipynb
Root cause: External Dependency Breakage

Good morning everyone,
please can someone help me to fix this ? I am having an issue running this block of code

```
# or as context manager 
with tru_query_engine_recorder as recording: 
    query_engine.query("What did the author do growing up?")
```


```
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[14], line 2
      1 # or as context manager
----> 2 with tru_query_engine_recorder as recording:
      3     query_engine.query("What did the author do growing up?")

File ~/anaconda3/envs/llamaindex/lib/python3.11/site-packages/trulens_eval/app.py:739, in App.__exit__(self, exc_type, exc_value, exc_tb)
    736 self.recording_contexts.reset(ctx.token)
    738 if exc_type is not None:
--> 739     raise exc_value
    741 return

Cell In[14], line 3
      1 # or as context manager
      2 with tru_query_engine_recorder as recording:
----> 3     query_engine.query("What did the author do growing up?")

File ~/anaconda3/envs/llamaindex/lib/python3.11/site-packages/trulens_eval/instruments.py:784, in Instrument.tracked_method_wrapper.<locals>.tru_wrapper(*args, **kwargs)
    778     # If stack has only 1 thing on it, we are looking at a "root
    779     # call". Create a record of the result and notify the app:
    781     if len(stack) == 1:
    782         # If this is a root call, notify app to add the completed record
    783         # into its containers:
--> 784         ctx.app._on_add_record(
    785             ctx=ctx,
    786             func=func,
    787             sig=sig,
    788             bindings=bindings,
    789             ret=rets,
    790             error=error,
    791             perf=Perf(start_time=start_time, end_time=end_time),
    792             cost=cost
    793         )
    795 if error is not None:
    796     raise error

File ~/anaconda3/envs/llamaindex/lib/python3.11/site-packages/trulens_eval/app.py:782, in App._on_add_record(self, ctx, func, sig, bindings, ret, error, perf, cost)
    769     return Record(
    770         main_input=jsonify(main_in),
    771         main_output=jsonify(main_out),
   (...)
    778         meta=jsonify(record_metadata)
    779     )
    781 # Finishing record needs to be done in a thread lock, done there:
--> 782 record = ctx.finish_record(build_record)
    784 if error is not None:
    785     # May block on DB.
    786     self._handle_error(record=record, error=error)

File ~/anaconda3/envs/llamaindex/lib/python3.11/site-packages/trulens_eval/app.py:381, in RecordingContext.finish_record(self, calls_to_record)
    375 """
    376 Run the given function to build a record from the tracked calls and any
    377 pre-specified metadata.
    378 """
    380 with self.lock:
--> 381     record = calls_to_record(self.calls, self.record_metadata)
    382     self.calls = []
    383     self.records.append(record)

File ~/anaconda3/envs/llamaindex/lib/python3.11/site-packages/trulens_eval/app.py:766, in App._on_add_record.<locals>.build_record(calls, record_metadata)
    762 calls = list(calls)
    764 assert len(calls) > 0, "No information recorded in call."
--> 766 main_in = self.main_input(func, sig, bindings)
    767 main_out = self.main_output(func, sig, bindings, ret)
    769 return Record(
    770     main_input=jsonify(main_in),
    771     main_output=jsonify(main_out),
   (...)
    778     meta=jsonify(record_metadata)
    779 )

File ~/anaconda3/envs/llamaindex/lib/python3.11/site-packages/trulens_eval/tru_llama.py:279, in TruLlama.main_input(self, func, sig, bindings)
    277 str_or_bundle = bindings.arguments['str_or_query_bundle']
    278 if isinstance(str_or_bundle, QueryBundle):
--> 279     return str_or_bundle.query_str
    280 else:
    281     return str_or_bundle

AttributeError: 'str' object has no attribute 'query_str'
```

I am using `trulens 0.20.3 `and `llama-index-core 0.10.23.post1`

<!-- Greeting -->
Hey @Anderson2992, back at it with the coding conundrums, I see! Good to have you reaching out again. Hope this one hasn't been too much of a head-scratcher for you!

<!-- Answer -->
Based on the information you've provided and the similar issues I found in the trulens repository, it seems that the error you're encountering is due to a mismatch between the expected `QueryBundle` object and the string that's being passed in your code snippet.

The error `AttributeError: 'str' object has no attribute 'query_str'` suggests that the code is attempting to access an attribute `query_str` on a string object, which obviously does not have this attribute. This error occurs in the context of handling `str_or_query_bundle` in the provided code snippet. The logic checks if `str_or_bundle` is an instance of `QueryBundle` and if so, attempts to return `str_or_bundle.query_str`. However, if `str_or_bundle` is not a `QueryBundle` (i.e., it is a string), the code just returns `str_or_bundle` itself.

To resolve this issue, ensure that wherever `str_or_query_bundle` is being set or passed into the function that leads to this code execution, it correctly distinguishes between strings and `QueryBundle` objects. If a string is passed when a `QueryBundle` is expected, you'll need to adjust the logic to either convert the string to a `QueryBundle` object (if feasible and logical in your application context) or ensure that a `QueryBundle` object is passed in the first place.

Here's a hypothetical fix that involves checking the type of `str_or_bundle` and handling the string case differently if you have a way to convert a string to a `QueryBundle` or handle it differently:

```python
if 'str_or_query_bundle' in bindings.arguments:
    # llama_index specific
    str_or_bundle = bindings.arguments['str_or_query_bundle']
    if isinstance(str_or_bundle, QueryBundle):
        return str_or_bundle.query_str
    elif isinstance(str_or_bundle, str):
        # Handle the string case here. This could involve converting the string to a QueryBundle
        # if your application logic allows for such a conversion.
        # Example:
        # query_bundle = convert_string_to_query_bundle(str_or_bundle)
        # return query_bundle.query_str
        # OR simply return the string if that's the intended behavior
        return str_or_bundle
    else:
        # Handle other types if necessary
        pass
```

Please note that the `convert_string_to_query_bundle` function is hypothetical and would need to be implemented based on your application's logic and requirements.

Ensure that any conversion logic or handling of strings vs. `QueryBundle` objects aligns with the intended use of your application to avoid introducing new bugs.

In addition to the above, I found a similar closed issue in the trulens repository: [Llama Index quick start - str object has no attribute query_str](https://github.com/truera/trulens/issues/916). The suggested solution in this issue was to upgrade to the latest release of TruLens (0.24.0) which now supports llama-index versions greater than 0.10. This update should resolve the AttributeError: 'str' object has no attribute 'query_str'. 

Given that you're using `trulens` version `0.20.3`, it might be worth trying to upgrade to the latest version (`trulens-eval-0.26.0` at the time of writing) and see if that resolves your issue.

I hope this helps! If you have any further questions or if the issue persists after trying the above solutions, please don't hesitate to ask.

## Sources
- [[BUG]: When attribute is in String instead of response format , it gives error:](https://github.com/truera/trulens/issues/941)
- [Llama Index quick start - str object has no attribute query_str](https://github.com/truera/trulens/issues/916)
- [trulens_eval/trulens_eval/tru_llama.py](https://github.com/truera/trulens/blob/main/trulens_eval/trulens_eval/tru_llama.py)

<!-- Dosu Comment Footer -->
<details>
<summary>

#### About Dosu
</summary>

This response is meant to be useful and save you time. It is **not meant to be a precise solution**, but rather a starting point for your own research.

Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.

If you want to continue the conversation, start your reply with @dosu-bot.
</details>


Hey @Anderson2992 - can you update your trulens version?

`pip install -U trulens_eval`

Hi @joshreini1
Thank you for your help, I have updated my trulens version and the code is working now
Many thanks

Thanks for the update @Anderson2992 !