Input variables cannot be updated
Self Checks
- [X] This is only for bug report, if you would like to ask a question, please head to Discussions.
- [X] I have searched for existing issues search for existing issues, including closed ones.
- [X] I confirm that I am using English to submit this report (我已阅读并同意 Language Policy).
- [X] [FOR CHINESE USERS] 请务必使用英文提交 Issue,否则会被关闭。谢谢!:)
- [X] Please do not modify this template :) and fill in all the required fields.
Dify version
0.7.2
Cloud or Self Hosted
Self Hosted (Docker)
Steps to reproduce
In the same conversation, input variables cannot be updated by using the chatflow api.
✔️ Expected Behavior
input variables can be updated by setting the input param in the chatflow api.
❌ Actual Behavior
input variables cannot be updated by using the chatflow api.
@hanhaiszw Hello there! I'm a bot here to assist you with bugs, questions, and becoming a contributor. While you wait for a human maintainer, feel free to ask me anything.
I found a similar issue that might be relevant to your problem: seems that some variables are lost after the Parameter Extraction node. This issue is closed and was last updated on August 01, 2024. The suggested solutions include ensuring correct input variable selection, proper model configuration, accurate parameter definition, and correct node configuration, among other things.
For updating input variables in a conversation, the VariableAssignerNode class and the update_conversation_variable function are responsible for handling this. The VariableAssignerNode supports different write modes (OVER_WRITE, APPEND, CLEAR) to update variables. Additionally, the useChatWithHistory hook in web/app/components/base/chat/chat-with-history/hooks.tsx manages conversation states and updates input variables.
Here is a relevant code snippet from the VariableAssignerNode class:
class VariableAssignerNode(BaseNode):
# ...
def _run(self, variable_pool: VariablePool) -> NodeRunResult:
data = cast(VariableAssignerData, self.node_data)
# Should be String, Number, Object, ArrayString, ArrayNumber, ArrayObject
original_variable = variable_pool.get(data.assigned_variable_selector)
if not isinstance(original_variable, Variable):
raise VariableAssignerNodeError('assigned variable not found')
match data.write_mode:
case WriteMode.OVER_WRITE:
income_value = variable_pool.get(data.input_variable_selector)
if not income_value:
raise VariableAssignerNodeError('input value not found')
updated_variable = original_variable.model_copy(update={'value': income_value.value})
case WriteMode.APPEND:
income_value = variable_pool.get(data.input_variable_selector)
if not income_value:
raise VariableAssignerNodeError('input value not found')
updated_value = original_variable.value + [income_value.value]
updated_variable = original_variable.model_copy(update({'value': updated_value})
case WriteMode.CLEAR:
income_value = get_zero_value(original_variable.value_type)
updated_variable = original_variable.model_copy(update({'value': income_value.to_object()})
case _:
raise VariableAssignerNodeError(f'unsupported write mode: {data.write_mode}')
# Over write the variable.
variable_pool.add(data.assigned_variable_selector, updated_variable)
# Update conversation variable.
conversation_id = variable_pool.get(['sys', 'conversation_id'])
if not conversation_id:
raise VariableAssignerNodeError('conversation_id not found')
update_conversation_variable(conversation_id=conversation_id.text, variable=updated_variable)
return NodeRunResult(
status=WorkflowNodeExecutionStatus.SUCCEEDED,
inputs={
'value': income_value.to_object(),
},
)
def update_conversation_variable(conversation_id: str, variable: Variable):
stmt = select(ConversationVariable).where(
ConversationVariable.id == variable.id, ConversationVariable.conversation_id == conversation_id
)
with Session(db.engine) as session:
row = session.scalar(stmt)
if not row:
raise VariableAssignerNodeError('conversation variable not found in the database')
row.data = variable.model_dump_json()
session.commit()
Additionally, the useChatWithHistory hook manages conversation states and updates input variables:
const handleNewConversationInputsChange = useCallback((newInputs: Record<string, any>) => {
newConversationInputsRef.current = newInputs
setNewConversationInputs(newInputs)
}, [])
const handleChangeConversation = useCallback((conversationId: string) => {
currentChatInstanceRef.current.handleStop()
setNewConversationId('')
handleConversationIdInfoChange(conversationId)
if (conversationId === '' && !checkInputsRequired(true))
setShowConfigPanelBeforeChat(true)
else
setShowConfigPanelBeforeChat(false)
}, [handleConversationIdInfoChange, setShowConfigPanelBeforeChat, checkInputsRequired])
These methods ensure that input variables are correctly updated and managed throughout the conversation lifecycle [1][2][3].
To continue talking to Dosu, mention @dosu.