Repository: truera/trulens
Issue: OpenAI Chat LLM with ChatPromptTemplate raises error with TrueChain
Root cause: Validation Gap

Hi,

I'm trying to integrate trulens eval in our setup.
We are using ChatOpenAI model with ChatPromptTemplate in langchain.
When calling the chain directly, it works fine. Doing the same through TruChain results in an error.
Versions:
trulens-eval==0.10.0
langchain==0.0.266

This is the code reproducing the issue.
It demonstrates that calling the chain directly works.

```
from trulens_eval import TruChain
from langchain.chat_models import ChatOpenAI
from langchain.chains import LLMChain
from langchain.schema import SystemMessage
from langchain.prompts.chat import ChatPromptTemplate


llm = ChatOpenAI(temperature=0.9)
# you need to set the Open AI API Key 

prompt = ChatPromptTemplate.from_messages(
    [SystemMessage(content="You are a friendly bot, who speaks like a dog")]
)

chain = LLMChain(llm=llm, prompt=prompt, verbose=True)

truchain = TruChain(
    chain,
    app_id="Chain1_ChatApplication",
)

input = {"input": "Hello"}
result_chain = chain(input)
print("Result from chain works fine: " + str(result_chain))
result = truchain(input)
print("Result from trulens: " + str(result))
```


Able to repro, getting the following error:

`ERROR:trulens_eval.app:Traceback (most recent call last):
  File "/usr/local/lib/python3.10/dist-packages/trulens_eval/app.py", line 680, in with_record
    main_in = self.main_input(func, sig, bindings)
  File "/usr/local/lib/python3.10/dist-packages/trulens_eval/tru_chain.py", line 143, in main_input
    return ins[self.app.input_keys[0]]
IndexError: list index out of range

WARNING:trulens_eval.app:No intrumented methods called. This may be due to missing instrumentation of relevant methods. Methods currently instrumented are: 
Object at 0x7ac6b7becdc0:
	<function Chain.__call__ at 0x7ac6b94b5480> with path *.__app__.app
	<function LLMChain._call at 0x7ac6b94b5c60> with path *.__app__.app
	<function LLMChain._acall at 0x7ac6b94b6170> with path *.__app__.app
	<function Chain.acall at 0x7ac6b94b5510> with path *.__app__.app
	<function Chain._call at 0x7ac6b94b5360> with path *.__app__.app
	<function Chain._acall at 0x7ac6b94b53f0> with path *.__app__.app`
	
Guessing this is from Langchain moving their classes. @piotrm0 can you take a look?

Hi, the issue here is that the chain has no inputs. The arg "input" is ignored by langchain (you can set it to anything and the answer will be the same) but in trulens we try to find the input to the chain and when querying it for its list of inputs, we get none. I am working on a fix to trulens to give a user a warning when this happens. For now, you can adjust your chain to include an input:

```python
from trulens_eval import TruChain
from langchain.chat_models import ChatOpenAI
from langchain.chains import LLMChain
from langchain.schema import SystemMessage
from langchain.prompts.chat import ChatPromptTemplate


llm = ChatOpenAI(temperature=0.9)
# you need to set the Open AI API Key 

prompt = ChatPromptTemplate.from_messages(
    [('system', "You are a friendly bot, who speaks like a dog. Answer this question: {question}")]
)

chain = LLMChain(llm=llm, prompt=prompt, verbose=True)

truchain = TruChain(
    chain,
    app_id="Chain1_ChatApplication",
)

input = {"question": "What is 1+1?"}
result_chain = chain(input)
print("Result from chain works fine: " + str(result_chain))
result = truchain(input)
print("Result from trulens: " + str(result))
```

Thanks a lot for the feedback.
I could make it work now with the sync call.

But I am facing another issue, hope it is fine if I am posting it here.

I am using async function of LangChain.
I have tried using the truelens-eval async function according to [this documentation](https://www.trulens.org/trulens_eval/langchain_instrumentation/#example-usage), but I've got an error.
```
Error calling wrapped function acall.
asyncio.exceptions.CancelledError
....
unhandled exception during asyncio.run() shutdown
....
File "..\.venv\lib\site-packages\trulens_eval\app.py", line 643, in awith_record
ret_record = self._post_record(
TypeError: App._post_record() takes 1 positional argument but 6 were given
```

This is my code:
```
from trulens_eval import TruChain
from langchain.chat_models import ChatOpenAI
from langchain.chains import LLMChain
from langchain.prompts.chat import ChatPromptTemplate
from langchain.callbacks.streaming_aiter import AsyncIteratorCallbackHandler
import asyncio
import trulens_eval.utils.python  # makes sure asyncio gets instrumented

prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "You are a friendly bot, who speaks like a {animal} and answers questions.",
        ),
        ("human", "{question}"),
    ]
)

callback = AsyncIteratorCallbackHandler()

llm = ChatOpenAI(
    temperature=0.0,
    streaming=True,  # important
    callbacks=[callback],  # callback can be here or below in acall_with_record
)
async_chain = LLMChain(llm=llm, prompt=prompt, verbose=True)

async_tc = TruChain(
    async_chain,
    app_id="Chain1_ChatApplication",
)

input = {"animal": "dog", "question": "What is 1+1?"}


async def run():
    asyncio.create_task(async_tc.acall_with_record(inputs=input))
    async for token in callback.aiter():
        print(token)


asyncio.run(run())

```

> TypeError: App._post_record() takes 1 positional argument but 6 were given

Hi @molntamas ; this might have been a bug which I believe is fixed in current main and should be fixed in the next release to be out shortly.  Interesting example, by the way. animal="cowboy" is a good one.

Thanks @piotrm0, the async call works fine with version 0.11.0.
From my perspective the issue is resolved.