The outout of the Chat Input is not been recognized as text by OpenAI model
DevPaby opened this issue · comments
Describe the bug
-
I have implemented the flow:
Chat Input [output message/text] -> [input] OpenAI Model [output text] -> [input] Chat Output. -
When running the playground chat to test the flow I receive the error message:
Error building vertex Azure OpenAI: 2 validation errors for HumanMessage content str type expected (type=type_error.str) content value is not a valid list (type=type_error.list) -
Input Chat
:
from typing import Optional
from langflow.base.io.chat import ChatComponent
from langflow.schema.message import Message
from langflow.field_typing import Text
from typing import Union
class ChatInput(ChatComponent):
display_name = "Chat Input"
description = "Get chat inputs from the Playground."
icon = "ChatInput"
def build_config(self):
build_config = super().build_config()
build_config["input_value"] = {
"input_types": [],
"display_name": "Text",
"multiline": True,
}
build_config["return_message"] = {
"display_name": "Return Record",
"advanced": True,
}
return build_config
def build(
self,
sender: Optional[str] = "User",
sender_name: Optional[str] = "User",
input_value: Optional[str] = None,
files: Optional[list[str]] = None,
session_id: Optional[str] = None,
return_message: Optional[bool] = True,
) -> Union[Message, Text]:
# THis has been included to make sure the input is a string
if isinstance(input_value, list):
input_value = " ".join(input_value)
elif not isinstance(input_value, str):
input_value = str(input_value)
# Included to check the output of the Chat Input
print(f"Processed input_value: {input_value} (type: {type(input_value)})")
# Output:
"""
Processed input_value: Hello (type: <class 'str'>)
D:\Dev\LangChain\lesson1\venv\Lib\site-packages\pydantic\main.py:1042: PydanticDeprecatedSince20: The __fields__
attribute is deprecated, use model_fields
instead. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.7/migration/
warnings.warn(
D:\Dev\LangChain\lesson1\venv\Lib\site-packages\pydantic\main.py:347: UserWarning: Pydantic serializer warnings:
Expected Union[str, dict[any, any], general-fields]
but got list
- serialized value may not be as expected
return self.pydantic_serializer.to_python(
"""
return super().build_with_record(
sender=sender,
sender_name=sender_name,
input_value=input_value,
files=files,
session_id=session_id,
return_message=return_message,
)
Screenshots
Hello, @DevPaby! I'm here to help you with any issues or questions you have. Feel free to ask me anything!
The error you're encountering indicates that the HumanMessage
content is expected to be a string, but it is being received as a list. This issue can be resolved by ensuring that the input_value
in the ChatInput
component is always a string before it is passed to the OpenAI
model.
Your current implementation already includes a check to convert input_value
to a string if it is a list or any other type. However, the error suggests that this conversion might not be happening correctly in all cases.
Here is a refined version of your ChatInput
component to ensure the input_value
is always a string:
from typing import Optional, Union
from langflow.base.io.chat import ChatComponent
from langflow.schema.message import Message
from langflow.field_typing import Text
class ChatInput(ChatComponent):
display_name = "Chat Input"
description = "Get chat inputs from the Playground."
icon = "ChatInput"
def build_config(self):
build_config = super().build_config()
build_config["input_value"] = {
"input_types": [],
"display_name": "Text",
"multiline": True,
}
build_config["return_message"] = {
"display_name": "Return Record",
"advanced": True,
}
return build_config
def build(
self,
sender: Optional[str] = "User",
sender_name: Optional[str] = "User",
input_value: Optional[str] = None,
files: Optional[list[str]] = None,
session_id: Optional[str] = None,
return_message: Optional[bool] = True,
) -> Union[Message, Text]:
# Ensure input_value is a string
if isinstance(input_value, list):
input_value = " ".join(input_value)
elif not isinstance(input_value, str):
input_value = str(input_value)
# Debugging output
print(f"Processed input_value: {input_value} (type: {type(input_value)})")
return super().build_with_record(
sender=sender,
sender_name=sender_name,
input_value=input_value,
files=files,
session_id=session_id,
return_message=return_message,
)
Additionally, ensure that the OpenAI
model component is correctly configured to handle the input_value
as a string. The expected structure and data type for the HumanMessage
content in the OpenAI model component is Text
[1].
If the issue persists, double-check the flow configuration and ensure that the input_value
is correctly passed as a string throughout the entire flow.
@dosu, You provide the same code I gave you. I have tried that code and its not working. Any other way to solve this?
To resolve the issue where the output of the Chat Input is not being recognized as text by the OpenAI model, you need to ensure that the value
passed to the InputListComponent
is always an array. The provided code already includes a check to convert a string value
to an array:
if (typeof value === "string") {
value = [value];
}
Make sure this conversion is correctly applied before the value
is used. This ensures that the value
is always in the expected array format, preventing the error "content str type expected (type=type_error.str) content value is not a valid list (type=type_error.list)".
Here's the relevant part of the code with the conversion:
import { useEffect } from "react";
import { InputListComponentType } from "../../types/components";
import _ from "lodash";
import { classNames } from "../../utils/utils";
import IconComponent from "../genericIconComponent";
import { Input } from "../ui/input";
export default function InputListComponent({
value,
onChange,
disabled,
editNode = false,
componentName,
playgroundDisabled,
}: InputListComponentType): JSX.Element {
useEffect(() => {
if (disabled && value.length > 0 && value[0] !== "") {
onChange([""]);
}
}, [disabled]);
// @TODO Recursive Character Text Splitter - the value might be in string format, whereas the InputListComponent specifically requires an array format. To ensure smooth operation and prevent potential errors, it's crucial that we handle the conversion from a string to an array with the string as its element.
if (typeof value === "string") {
value = [value];
}
if (!value?.length) value = [""];
return (
<div
className={classNames(
value.length > 1 && editNode ? "my-1" : "",
"flex flex-col gap-3",
)}
>
{value.map((singleValue, idx) => {
return (
<div key={idx} className="flex w-full gap-3">
<Input
disabled={disabled || playgroundDisabled}
type="text"
value={singleValue}
className={editNode ? "input-edit-node" : ""}
placeholder="Type something..."
onChange={(event) => {
let newInputList = _.cloneDeep(value);
newInputList[idx] = event.target.value;
onChange(newInputList);
}}
data-testid={
`input-list-input${editNode ? "-edit" : ""}_${componentName}-` +
idx
}
/>
{idx === value.length - 1 ? (
<button
onClick={(e) => {
let newInputList = _.cloneDeep(value);
newInputList.push("");
onChange(newInputList);
e.preventDefault();
}}
data-testid={
`input-list-plus-btn${
editNode ? "-edit" : ""
}_${componentName}-` + idx
}
disabled={disabled || playgroundDisabled}
>
<IconComponent
name="Plus"
className={"h-4 w-4 hover:text-accent-foreground"}
/>
</button>
) : (
<button
data-testid={
`input-list-minus-btn${
editNode ? "-edit" : ""
}_${componentName}-` + idx
}
onClick={(e) => {
let newInputList = _.cloneDeep(value);
newInputList.splice(idx, 1);
onChange(newInputList);
e.preventDefault();
}}
disabled={disabled || playgroundDisabled}
>
<IconComponent
name="X"
className={`h-4 w-4 ${
disabled || playgroundDisabled
? ""
: "hover:text-accent-foreground"
}`}
/>
</button>
)}
</div>
);
})}
</div>
);
}
Ensure that this code is correctly implemented and that the value
passed to the InputListComponent
is properly converted to an array if it is initially a string. This should resolve the error you are encountering [1][2].
Please insert the API key directly instead of using a variable. There is still a bug with using the variable.
duplicated of #2182 and working 1.0.5