Semantics for VariableAssigner in current implementation
Currently, VariableAssigner v1 and v2 are the only nodes allowed to mutate variables during workflow execution.
However, the implementation of the two nodes currently does not restrict which variables could be mutated. The only restriction comes from the workflow orchestration UI.
More specifically, the frontend UI limit the assignment targets to conversation variables for top-level VariableAssigner nodes:
For VariableAssigner nodes inside Loop / Iteration nodes, the loop index variable, iteration index variable and iteration value variable are also assignable:
Since graphon has been extracted as a library, the frontend limitation does not apply anymore. The semantics of the VariableAssigner node needs to be clarified. If the limit still applies to VariableAssigner node, I believe we should implement this limit in code, instead of allowing the users of graphon to assign to variables which are considered immutable.
DSL for the example above
app:
description: ''
icon: 🤖
icon_background: '#FFEAD5'
icon_type: emoji
mode: advanced-chat
name: AssignerSemantics
use_icon_as_answer_icon: false
dependencies: []
kind: app
version: 0.6.0
workflow:
conversation_variables:
- description: test
id: e39ede7e-e784-4498-9bfb-66e4a9bf8fb3
name: conv_var
selector:
- conversation
- conv_var
value: test
value_type: string
environment_variables: []
features:
file_upload:
allowed_file_extensions:
- .JPG
- .JPEG
- .PNG
- .GIF
- .WEBP
- .SVG
allowed_file_types:
- image
allowed_file_upload_methods:
- local_file
- remote_url
enabled: false
fileUploadConfig:
attachment_image_file_size_limit: 2
audio_file_size_limit: 50
batch_count_limit: 5
file_size_limit: 15
file_upload_limit: 50
image_file_batch_limit: 10
image_file_size_limit: 10
single_chunk_attachment_limit: 10
video_file_size_limit: 100
workflow_file_upload_limit: 10
image:
enabled: false
number_limits: 3
transfer_methods:
- local_file
- remote_url
number_limits: 3
opening_statement: ''
retriever_resource:
enabled: true
sensitive_word_avoidance:
enabled: false
speech_to_text:
enabled: false
suggested_questions: []
suggested_questions_after_answer:
enabled: false
text_to_speech:
enabled: false
language: ''
voice: ''
graph:
edges:
- data:
isInIteration: false
isInLoop: false
sourceType: assigner
targetType: loop
id: 1775718594480-source-1775718589443-target
source: '1775718594480'
sourceHandle: source
target: '1775718589443'
targetHandle: target
type: custom
zIndex: 0
- data:
isInIteration: false
isInLoop: false
sourceType: assigner
targetType: iteration
id: 1775718594480-source-1775718633046-target
source: '1775718594480'
sourceHandle: source
target: '1775718633046'
targetHandle: target
type: custom
zIndex: 0
- data:
isInIteration: true
isInLoop: false
iteration_id: '1775718633046'
sourceType: iteration-start
targetType: assigner
id: 1775718633046start-source-1775718642679-target
source: 1775718633046start
sourceHandle: source
target: '1775718642679'
targetHandle: target
type: custom
zIndex: 1002
- data:
isInIteration: false
isInLoop: false
sourceType: loop
targetType: answer
id: 1775718589443-source-1775718657295-target
source: '1775718589443'
sourceHandle: source
target: '1775718657295'
targetHandle: target
type: custom
zIndex: 0
- data:
isInLoop: false
sourceType: iteration
targetType: answer
id: 1775718633046-source-1775718657295-target
source: '1775718633046'
sourceHandle: source
target: '1775718657295'
targetHandle: target
type: custom
zIndex: 0
- data:
isInIteration: false
isInLoop: true
loop_id: '1775718589443'
sourceType: loop-start
targetType: assigner
id: 1775718589443start-source-1775718669662-target
source: 1775718589443start
sourceHandle: source
target: '1775718669662'
targetHandle: target
type: custom
zIndex: 1002
- data:
isInIteration: false
isInLoop: false
sourceType: start
targetType: code
id: 1775707133096-source-1775719093003-target
source: '1775707133096'
sourceHandle: source
target: '1775719093003'
targetHandle: target
type: custom
zIndex: 0
- data:
isInIteration: false
isInLoop: false
sourceType: code
targetType: assigner
id: 1775719093003-source-1775718594480-target
source: '1775719093003'
sourceHandle: source
target: '1775718594480'
targetHandle: target
type: custom
zIndex: 0
- data:
isInIteration: true
isInLoop: false
iteration_id: '1775718633046'
sourceType: assigner
targetType: template-transform
id: 1775718642679-source-1775719151996-target
source: '1775718642679'
sourceHandle: source
target: '1775719151996'
targetHandle: target
type: custom
zIndex: 1002
nodes:
- data:
selected: false
title: User Input
type: start
variables: []
height: 73
id: '1775707133096'
position:
x: 0
y: 79
positionAbsolute:
x: 0
y: 79
sourcePosition: right
targetPosition: left
type: custom
width: 242
- data:
break_conditions:
- comparison_operator: <
id: 2d7dfa2c-bd6a-4c12-b907-ff509e6bb1d5
value: '10'
varType: number
variable_selector:
- '1775718589443'
- index
error_handle_mode: terminated
height: 204
logical_operator: and
loop_count: 10
loop_variables:
- id: 4b32f071-42e8-4b7b-88a5-748cb2f3c60a
label: index
value: '0'
value_type: constant
var_type: number
selected: false
start_node_id: 1775718589443start
title: Loop
type: loop
width: 486
height: 204
id: '1775718589443'
position:
x: 1046
y: 0
positionAbsolute:
x: 1046
y: 0
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 486
zIndex: 1
- data:
desc: ''
isInLoop: true
selected: false
title: ''
type: loop-start
draggable: false
height: 48
id: 1775718589443start
parentId: '1775718589443'
position:
x: 60
y: 78
positionAbsolute:
x: 1106
y: 78
selectable: false
sourcePosition: right
targetPosition: left
type: custom-loop-start
width: 44
zIndex: 1002
- data:
items:
- input_type: constant
operation: set
value: '1'
variable_selector:
- conversation
- conv_var
write_mode: over-write
selected: false
title: Variable Assigner
type: assigner
version: '2'
height: 84
id: '1775718594480'
position:
x: 684
y: 74
positionAbsolute:
x: 684
y: 74
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 242
- data:
error_handle_mode: terminated
flatten_output: true
height: 230
is_parallel: false
iterator_input_type: array[string]
iterator_selector:
- '1775719093003'
- strings
output_selector:
- '1775719151996'
- output
output_type: array[string]
parallel_nums: 10
selected: false
start_node_id: 1775718633046start
title: Iteration
type: iteration
width: 808
height: 230
id: '1775718633046'
position:
x: 1046
y: 284
positionAbsolute:
x: 1046
y: 284
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 808
zIndex: 1
- data:
desc: ''
isInIteration: true
selected: false
title: ''
type: iteration-start
draggable: false
height: 48
id: 1775718633046start
parentId: '1775718633046'
position:
x: 60
y: 91
positionAbsolute:
x: 1106
y: 375
selectable: false
sourcePosition: right
targetPosition: left
type: custom-iteration-start
width: 44
zIndex: 1002
- data:
isInIteration: true
isInLoop: false
items:
- input_type: constant
operation: set
value: 0
variable_selector:
- '1775718633046'
- index
write_mode: over-write
- input_type: variable
operation: over-write
value:
- sys
- query
variable_selector:
- '1775718633046'
- item
write_mode: over-write
iteration_id: '1775718633046'
selected: true
title: Iter Var Assigner
type: assigner
version: '2'
height: 110
id: '1775718642679'
parentId: '1775718633046'
position:
x: 184
y: 60
positionAbsolute:
x: 1230
y: 344
selected: true
sourcePosition: right
targetPosition: left
type: custom
width: 242
zIndex: 1002
- data:
answer: '0'
selected: false
title: Answer
type: answer
variables: []
height: 100
id: '1775718657295'
position:
x: 1974
y: 69
positionAbsolute:
x: 1974
y: 69
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 242
- data:
isInIteration: false
isInLoop: true
items:
- input_type: constant
operation: set
value: 0
variable_selector:
- '1775718589443'
- index
write_mode: over-write
loop_id: '1775718589443'
selected: false
title: Loop Var Assigner
type: assigner
version: '2'
height: 84
id: '1775718669662'
parentId: '1775718589443'
position:
x: 184
y: 60
positionAbsolute:
x: 1230
y: 60
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 242
zIndex: 1002
- data:
code: "\ndef main():\n return {\n \"strings\": [],\n }\n"
code_language: python3
outputs:
strings:
children: null
type: array[string]
selected: false
title: VariableCreator
type: code
variables: []
height: 52
id: '1775719093003'
position:
x: 342
y: 90
positionAbsolute:
x: 342
y: 90
sourcePosition: right
targetPosition: left
type: custom
width: 242
- data:
isInIteration: true
isInLoop: false
iteration_id: '1775718633046'
selected: false
template: '0'
title: Template
type: template-transform
variables: []
height: 52
id: '1775719151996'
parentId: '1775718633046'
position:
x: 506
y: 89
positionAbsolute:
x: 1552
y: 373
sourcePosition: right
targetPosition: left
type: custom
width: 242
zIndex: 1002
viewport:
x: 211
y: 216
zoom: 0.7
rag_pipeline_variables: []
Semantics for
VariableAssignerin current implementationCurrently,
VariableAssignerv1 and v2 are the only nodes allowed to mutate variables during workflow execution.However, the implementation of the two nodes currently does not restrict which variables could be mutated. The only restriction comes from the workflow orchestration UI.
More specifically, the frontend UI limit the assignment targets to conversation variables for top-level
VariableAssignernodes:For
VariableAssignernodes insideLoop/Iterationnodes, the loop index variable, iteration index variable and iteration value variable are also assignable:Since graphon has been extracted as a library, the frontend limitation does not apply anymore. The semantics of the
VariableAssignernode needs to be clarified. If the limit still applies toVariableAssignernode, I believe we should implement this limit in code, instead of allowing the users of graphon to assign to variables which are considered immutable.DSL for the example above