meta_workflows 0.9.31 → 0.9.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/javascripts/meta_workflows/controllers/lexi_form_submit_controller.js +17 -3
- data/app/assets/javascripts/meta_workflows/controllers/structured_form_submit_controller.js +45 -30
- data/app/assets/stylesheets/meta_workflows/application.css +94 -31
- data/app/helpers/concerns/meta_workflows/frame_id_helper.rb +21 -0
- data/app/helpers/concerns/meta_workflows/partial_paths_helper.rb +53 -0
- data/app/helpers/concerns/meta_workflows/ui_state_helper.rb +38 -0
- data/app/helpers/meta_workflows/meta_workflows_helper.rb +42 -68
- data/app/jobs/meta_workflows/human_input_job.rb +3 -2
- data/app/models/meta_workflows/workflow_execution.rb +10 -0
- data/app/models/meta_workflows/workflow_step.rb +16 -0
- data/app/services/meta_workflows/lexi_chat_data_service.rb +59 -0
- data/app/views/meta_workflows/_checkbox_input.html.erb +1 -15
- data/app/views/meta_workflows/_lexi_chat_alpha_tray.html.erb +7 -27
- data/app/views/meta_workflows/_lexi_chat_input_area.html.erb +20 -0
- data/app/views/meta_workflows/_lexi_chat_messages.html.erb +13 -0
- data/app/views/meta_workflows/_lexi_chat_right_tray.html.erb +13 -24
- data/app/views/meta_workflows/_radio_input.html.erb +1 -0
- data/app/views/meta_workflows/_slider_input.html.erb +1 -0
- data/app/views/meta_workflows/_structured_input.html.erb +4 -9
- data/db/migrate/20250721195735_add_initial_execution_to_meta_workflows_workflow_steps.rb +5 -0
- data/lib/meta_workflows/version.rb +1 -1
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3496946526cd97d8ed5722ce2aef1c3e5a481e9345f41ee5a3902a001c7a1d9a
|
4
|
+
data.tar.gz: 675a6e8c765f6479e7c766e0ae34d458c70b0804aebf720d0584606c734fe956
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 66d6d6ab599efe41489eba40a19e2c80d86e4331193981fc45d4deed838ae946da59d41eebc45639a747b9e7c9b8c2c67cf1b18a37387ad8aa310fd054c0eadb
|
7
|
+
data.tar.gz: 24998761fb152ca8e78d3ffd4ab1c2b45863a84772e3678127066c37b8188a4e3982a2fdae7d981dc3ae85515668f6fab2bda5fb07bd767cc10844920bef8121
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { Controller } from '@hotwired/stimulus';
|
2
2
|
|
3
3
|
export default class extends Controller {
|
4
|
-
static targets = ['textarea', 'form', 'structuredInputForm', 'hiddenMessage'];
|
4
|
+
static targets = ['textarea', 'form', 'structuredInputForm', 'hiddenMessage', 'structuredInput'];
|
5
5
|
|
6
6
|
connect() {
|
7
7
|
this.submitted = false;
|
@@ -14,7 +14,6 @@ export default class extends Controller {
|
|
14
14
|
handleKeyDown(event) {
|
15
15
|
if (event.key === 'Enter' && !event.shiftKey) {
|
16
16
|
event.preventDefault();
|
17
|
-
event.stopPropagation();
|
18
17
|
this.handleSubmit();
|
19
18
|
}
|
20
19
|
}
|
@@ -24,7 +23,22 @@ export default class extends Controller {
|
|
24
23
|
return;
|
25
24
|
}
|
26
25
|
|
27
|
-
|
26
|
+
// Check if we have structured input selections
|
27
|
+
const hasStructuredSelections = this.hasStructuredInputTargets.some(input =>
|
28
|
+
input.checked || (input.type === 'range' && input.value !== input.min)
|
29
|
+
);
|
30
|
+
|
31
|
+
if (hasStructuredSelections) {
|
32
|
+
// Submit the structured form to StructuredHumansController
|
33
|
+
this.submitted = true;
|
34
|
+
this.hideStructuredInputForm();
|
35
|
+
this.structuredInputFormTarget.requestSubmit();
|
36
|
+
return;
|
37
|
+
}
|
38
|
+
|
39
|
+
// Otherwise, handle normal text submission to HumansController
|
40
|
+
const textValue = this.hasTextareaTarget ? this.textareaTarget.value.trim() : '';
|
41
|
+
if (!textValue) {
|
28
42
|
return;
|
29
43
|
}
|
30
44
|
|
@@ -1,42 +1,61 @@
|
|
1
1
|
import { Controller } from '@hotwired/stimulus';
|
2
2
|
|
3
3
|
export default class extends Controller {
|
4
|
-
static targets = ['form', '
|
4
|
+
static targets = ['form', 'checkbox', 'slider'];
|
5
5
|
|
6
6
|
connect() {
|
7
7
|
this.submitted = false;
|
8
|
+
this.setupKeyboardListener();
|
8
9
|
}
|
9
10
|
|
10
|
-
|
11
|
-
this.
|
11
|
+
disconnect() {
|
12
|
+
this.removeKeyboardListener();
|
12
13
|
}
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
setupKeyboardListener() {
|
16
|
+
this.keydownHandler = this.handleKeyDown.bind(this);
|
17
|
+
if (this.hasFormTarget) {
|
18
|
+
this.formTarget.addEventListener('keydown', this.keydownHandler);
|
19
|
+
}
|
17
20
|
}
|
18
21
|
|
19
|
-
|
20
|
-
this.
|
22
|
+
removeKeyboardListener() {
|
23
|
+
if (this.keydownHandler && this.hasFormTarget) {
|
24
|
+
this.formTarget.removeEventListener('keydown', this.keydownHandler);
|
25
|
+
}
|
21
26
|
}
|
22
27
|
|
23
|
-
|
24
|
-
|
28
|
+
handleKeyDown(event) {
|
29
|
+
if (event.key === 'Enter' && !event.shiftKey) {
|
30
|
+
// Check if we have selected checkboxes
|
31
|
+
const selectedCheckboxes = this.checkboxTargets.filter(checkbox => checkbox.checked);
|
32
|
+
|
33
|
+
if (selectedCheckboxes.length > 0) {
|
34
|
+
event.preventDefault();
|
35
|
+
event.stopPropagation();
|
36
|
+
this.handleSubmit();
|
37
|
+
}
|
38
|
+
}
|
25
39
|
}
|
26
40
|
|
27
|
-
|
28
|
-
this.
|
41
|
+
sliderTargetConnected(slider) {
|
42
|
+
this.updateSliderAria(slider);
|
43
|
+
this.updateSliderFill(slider);
|
29
44
|
}
|
30
45
|
|
31
|
-
|
32
|
-
|
46
|
+
updateSliderAria(slider) {
|
47
|
+
slider.setAttribute('aria-valuenow', slider.value);
|
48
|
+
slider.setAttribute('aria-valuetext', slider.value);
|
49
|
+
}
|
33
50
|
|
34
|
-
|
35
|
-
|
51
|
+
updateSliderFill(slider) {
|
52
|
+
const percentage = ((slider.value - slider.min) / (slider.max - slider.min)) * 100;
|
53
|
+
slider.style.setProperty('--slider-fill', `${percentage}%`);
|
36
54
|
}
|
37
55
|
|
38
|
-
|
39
|
-
this.
|
56
|
+
handleSliderChange(event) {
|
57
|
+
this.updateSliderAria(event.target);
|
58
|
+
this.updateSliderFill(event.target);
|
40
59
|
}
|
41
60
|
|
42
61
|
handleSubmit() {
|
@@ -48,19 +67,15 @@ export default class extends Controller {
|
|
48
67
|
this.hideFormAndSubmit();
|
49
68
|
}
|
50
69
|
|
51
|
-
|
52
|
-
|
70
|
+
hideFormAndSubmit() {
|
71
|
+
// Hide the structured input form
|
72
|
+
if (this.hasFormTarget) {
|
73
|
+
this.formTarget.style.display = 'none';
|
74
|
+
}
|
53
75
|
|
54
|
-
|
55
|
-
|
76
|
+
// Submit the form to StructuredHumansController
|
77
|
+
if (this.hasFormTarget) {
|
78
|
+
this.formTarget.requestSubmit();
|
56
79
|
}
|
57
|
-
|
58
|
-
this.submitted = true;
|
59
|
-
this.hideFormAndSubmit();
|
60
|
-
}
|
61
|
-
|
62
|
-
hideFormAndSubmit() {
|
63
|
-
this.formTarget.style.display = 'none';
|
64
|
-
this.formTarget.requestSubmit();
|
65
80
|
}
|
66
81
|
}
|
@@ -840,8 +840,7 @@
|
|
840
840
|
padding: 1rem;
|
841
841
|
background-color: rgba(255, 255, 255, 0.9);
|
842
842
|
border-radius: 0.75rem;
|
843
|
-
|
844
|
-
margin-bottom: 1rem;
|
843
|
+
margin-bottom: .5rem;
|
845
844
|
}
|
846
845
|
|
847
846
|
.structured-input-options {
|
@@ -856,28 +855,28 @@
|
|
856
855
|
align-items: center;
|
857
856
|
gap: 0.75rem;
|
858
857
|
padding: 0.75rem 1rem;
|
859
|
-
border:
|
858
|
+
border: 2px solid transparent;
|
860
859
|
border-radius: 0.5rem;
|
861
860
|
background-color: white;
|
862
861
|
cursor: pointer;
|
863
862
|
transition: all 0.2s ease;
|
863
|
+
background-image: linear-gradient(white, white), linear-gradient(var(--gray-300), var(--gray-300));
|
864
|
+
background-origin: border-box;
|
865
|
+
background-clip: padding-box, border-box;
|
864
866
|
}
|
865
867
|
|
866
868
|
.structured-radio-option:hover {
|
867
|
-
background-
|
868
|
-
|
869
|
+
background-image: linear-gradient(white, white), linear-gradient(45deg, #F3B51C, #E87C66, #F3B51C, #E87C66);
|
870
|
+
background-size: auto, 300% 300%;
|
871
|
+
animation: animatedgradient 3s ease alternate infinite;
|
869
872
|
}
|
870
873
|
|
871
874
|
.structured-radio-option:has(.structured-radio-input:checked) {
|
872
875
|
background-color: var(--purple-50);
|
873
|
-
border-color: var(--purple-500);
|
874
876
|
}
|
875
877
|
|
876
878
|
.structured-radio-input {
|
877
|
-
|
878
|
-
height: 1.25rem;
|
879
|
-
accent-color: var(--purple-600);
|
880
|
-
cursor: pointer;
|
879
|
+
display: none;
|
881
880
|
}
|
882
881
|
|
883
882
|
.structured-radio-label {
|
@@ -894,27 +893,32 @@
|
|
894
893
|
align-items: center;
|
895
894
|
gap: 0.75rem;
|
896
895
|
padding: 0.75rem 1rem;
|
897
|
-
border:
|
896
|
+
border: 2px solid transparent;
|
898
897
|
border-radius: 0.5rem;
|
899
898
|
background-color: white;
|
900
899
|
cursor: pointer;
|
901
900
|
transition: all 0.2s ease;
|
901
|
+
background-image: linear-gradient(white, white), linear-gradient(var(--gray-300), var(--gray-300));
|
902
|
+
background-origin: border-box;
|
903
|
+
background-clip: padding-box, border-box;
|
902
904
|
}
|
903
905
|
|
904
906
|
.structured-checkbox-option:hover {
|
905
|
-
background-
|
906
|
-
|
907
|
+
background-image: linear-gradient(white, white), linear-gradient(45deg, #F3B51C, #E87C66, #F3B51C, #E87C66);
|
908
|
+
background-size: auto, 300% 300%;
|
909
|
+
animation: animatedgradient 3s ease alternate infinite;
|
907
910
|
}
|
908
911
|
|
909
912
|
.structured-checkbox-option:has(.structured-checkbox-input:checked) {
|
910
|
-
background-
|
911
|
-
border-color: var(--purple-500);
|
913
|
+
background-image: linear-gradient(white, white), linear-gradient(45deg, #F3B51C, #E87C66);
|
912
914
|
}
|
913
915
|
|
916
|
+
|
917
|
+
|
914
918
|
.structured-checkbox-input {
|
915
919
|
width: 1.25rem;
|
916
920
|
height: 1.25rem;
|
917
|
-
accent-color: var(--purple-
|
921
|
+
accent-color: var(--purple-700);
|
918
922
|
cursor: pointer;
|
919
923
|
}
|
920
924
|
|
@@ -929,12 +933,14 @@
|
|
929
933
|
/* Slider Styles */
|
930
934
|
.structured-slider-container {
|
931
935
|
padding: 1rem;
|
936
|
+
border: 1px solid var(--gray-300);
|
937
|
+
border-radius: 0.5rem;
|
938
|
+
background-color: var(--gray-50);
|
932
939
|
}
|
933
940
|
|
934
941
|
.structured-slider-labels {
|
935
942
|
display: flex;
|
936
943
|
justify-content: space-between;
|
937
|
-
margin-bottom: 1rem;
|
938
944
|
font-size: 0.875rem;
|
939
945
|
color: var(--gray-600);
|
940
946
|
font-weight: 500;
|
@@ -948,46 +954,90 @@
|
|
948
954
|
|
949
955
|
.structured-slider-input {
|
950
956
|
width: 100%;
|
951
|
-
height:
|
957
|
+
height: 1rem;
|
952
958
|
border-radius: 0.25rem;
|
953
|
-
background:
|
959
|
+
background: transparent;
|
954
960
|
outline: none;
|
955
961
|
-webkit-appearance: none;
|
956
962
|
appearance: none;
|
957
963
|
cursor: pointer;
|
964
|
+
--slider-fill: 0%;
|
965
|
+
border: none;
|
966
|
+
}
|
967
|
+
|
968
|
+
.structured-slider-input::-webkit-slider-runnable-track {
|
969
|
+
width: 100%;
|
970
|
+
height: 1rem;
|
971
|
+
border-radius: 0.25rem;
|
972
|
+
background: linear-gradient(90deg,
|
973
|
+
#F3B51C 0%,
|
974
|
+
#E87C66 var(--slider-fill),
|
975
|
+
#e5e7eb var(--slider-fill),
|
976
|
+
#e5e7eb 100%
|
977
|
+
);
|
978
|
+
background-size: 100% 100%;
|
979
|
+
background-repeat: no-repeat;
|
980
|
+
border: 1px solid var(--gray-300);
|
981
|
+
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
982
|
+
}
|
983
|
+
|
984
|
+
.structured-slider-input::-moz-range-track {
|
985
|
+
width: 100%;
|
986
|
+
height: 1rem;
|
987
|
+
border-radius: 0.25rem;
|
988
|
+
background: linear-gradient(90deg,
|
989
|
+
#F3B51C 0%,
|
990
|
+
#E87C66 var(--slider-fill),
|
991
|
+
#e5e7eb var(--slider-fill),
|
992
|
+
#e5e7eb 100%
|
993
|
+
);
|
994
|
+
background-size: 100% 100%;
|
995
|
+
background-repeat: no-repeat;
|
996
|
+
border: 1px solid var(--gray-300);
|
997
|
+
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
958
998
|
}
|
959
999
|
|
960
1000
|
.structured-slider-input::-webkit-slider-thumb {
|
961
1001
|
-webkit-appearance: none;
|
962
1002
|
appearance: none;
|
963
|
-
width:
|
964
|
-
height:
|
965
|
-
border-radius:
|
966
|
-
background: var(--purple-
|
1003
|
+
width: 2.25rem;
|
1004
|
+
height: 2.25rem;
|
1005
|
+
border-radius: 0.5625rem;
|
1006
|
+
background: var(--purple-700);
|
1007
|
+
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='white' viewBox='0 0 320 512'%3e%3cpath d='M96 480c-8.188 0-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L242.8 256L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z'/%3e%3c/svg%3e");
|
1008
|
+
background-size: 12px 12px;
|
1009
|
+
background-position: center;
|
1010
|
+
background-repeat: no-repeat;
|
967
1011
|
cursor: pointer;
|
968
1012
|
border: 2px solid white;
|
969
|
-
box-shadow: 0
|
1013
|
+
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.25);
|
970
1014
|
transition: all 0.2s ease;
|
1015
|
+
margin-top: -0.65rem;
|
971
1016
|
}
|
972
1017
|
|
973
1018
|
.structured-slider-input::-webkit-slider-thumb:hover {
|
974
|
-
background: var(--purple-
|
1019
|
+
background-color: var(--purple-800);
|
975
1020
|
transform: scale(1.1);
|
976
1021
|
}
|
977
1022
|
|
978
1023
|
.structured-slider-input::-moz-range-thumb {
|
979
|
-
width:
|
980
|
-
height:
|
981
|
-
border-radius:
|
982
|
-
background: var(--purple-
|
1024
|
+
width: 2.25rem;
|
1025
|
+
height: 2.25rem;
|
1026
|
+
border-radius: 0.5625rem;
|
1027
|
+
background: var(--purple-700);
|
1028
|
+
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='white' viewBox='0 0 320 512'%3e%3cpath d='M96 480c-8.188 0-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L242.8 256L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z'/%3e%3c/svg%3e");
|
1029
|
+
background-size: 12px 12px;
|
1030
|
+
background-position: center;
|
1031
|
+
background-repeat: no-repeat;
|
983
1032
|
cursor: pointer;
|
984
1033
|
border: 2px solid white;
|
985
|
-
box-shadow: 0
|
1034
|
+
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.25);
|
986
1035
|
transition: all 0.2s ease;
|
1036
|
+
margin-top: -0.65rem;
|
987
1037
|
}
|
988
1038
|
|
989
1039
|
.structured-slider-input::-moz-range-thumb:hover {
|
990
|
-
background: var(--purple-
|
1040
|
+
background-color: var(--purple-800);
|
991
1041
|
transform: scale(1.1);
|
992
1042
|
}
|
993
1043
|
|
@@ -1062,3 +1112,16 @@
|
|
1062
1112
|
white-space: nowrap;
|
1063
1113
|
border: 0;
|
1064
1114
|
}
|
1115
|
+
|
1116
|
+
/* Animated Gradient Keyframes */
|
1117
|
+
@keyframes animatedgradient {
|
1118
|
+
0% {
|
1119
|
+
background-position: 0% 50%;
|
1120
|
+
}
|
1121
|
+
50% {
|
1122
|
+
background-position: 100% 50%;
|
1123
|
+
}
|
1124
|
+
100% {
|
1125
|
+
background-position: 0% 50%;
|
1126
|
+
}
|
1127
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MetaWorkflows
|
4
|
+
module FrameIdHelper
|
5
|
+
def target_frame_id(record, **options)
|
6
|
+
base_id = "#{record.class.name.downcase}_#{record.id}"
|
7
|
+
|
8
|
+
return "#{base_id}_loader" if options[:loader]
|
9
|
+
return "#{base_id}_form" if options[:form]
|
10
|
+
return "#{base_id}_structured_input" if options[:structured_input]
|
11
|
+
return "#{base_id}_chat_history" if options[:chat_history]
|
12
|
+
return "#{base_id}_streaming" if options[:streaming]
|
13
|
+
|
14
|
+
base_id
|
15
|
+
end
|
16
|
+
|
17
|
+
def turbo_stream_name(record)
|
18
|
+
[record.class.name.downcase, record.id]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MetaWorkflows
|
4
|
+
module PartialPathsHelper
|
5
|
+
def meta_loader_message
|
6
|
+
'meta_workflows/loader_message'
|
7
|
+
end
|
8
|
+
|
9
|
+
def meta_error_message
|
10
|
+
'meta_workflows/error_message'
|
11
|
+
end
|
12
|
+
|
13
|
+
def meta_response_form
|
14
|
+
'meta_workflows/response_form_lexi'
|
15
|
+
end
|
16
|
+
|
17
|
+
def meta_structured_input
|
18
|
+
'meta_workflows/structured_input'
|
19
|
+
end
|
20
|
+
|
21
|
+
def meta_response
|
22
|
+
'meta_workflows/response_lexi'
|
23
|
+
end
|
24
|
+
|
25
|
+
def meta_chat_history
|
26
|
+
'meta_workflows/chat_history'
|
27
|
+
end
|
28
|
+
|
29
|
+
def meta_streaming_response
|
30
|
+
'meta_workflows/streaming_response'
|
31
|
+
end
|
32
|
+
|
33
|
+
def meta_redirect
|
34
|
+
'meta_workflows/redirect'
|
35
|
+
end
|
36
|
+
|
37
|
+
def meta_lexi_chat_right_tray
|
38
|
+
'meta_workflows/lexi_chat_right_tray'
|
39
|
+
end
|
40
|
+
|
41
|
+
def meta_lexi_chat_alpha_tray
|
42
|
+
'meta_workflows/lexi_chat_alpha_tray'
|
43
|
+
end
|
44
|
+
|
45
|
+
def meta_lexi_chat_messages
|
46
|
+
'meta_workflows/lexi_chat_messages'
|
47
|
+
end
|
48
|
+
|
49
|
+
def meta_lexi_chat_input_area
|
50
|
+
'meta_workflows/lexi_chat_input_area'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MetaWorkflows
|
4
|
+
module UiStateHelper
|
5
|
+
def random_chat_placeholder
|
6
|
+
[
|
7
|
+
'What would you like to improve?',
|
8
|
+
'Suggest an edit or ask for changes...',
|
9
|
+
'Let me know how I can improve this.',
|
10
|
+
'Not quite right? Let me know.',
|
11
|
+
'Edit, clarify, or request a change.',
|
12
|
+
'Happy with this, or want changes?'
|
13
|
+
].sample
|
14
|
+
end
|
15
|
+
|
16
|
+
def tray_state(tray)
|
17
|
+
(cookies['tray_'] && cookies['tray_'][tray.to_s]) || cookies["tray_#{tray}"] || 'expanded'
|
18
|
+
end
|
19
|
+
|
20
|
+
def chevron_direction(tray)
|
21
|
+
state = tray_state(tray)
|
22
|
+
case tray.to_s
|
23
|
+
when 'beta'
|
24
|
+
state == 'collapsed' ? 'fa-chevron-right' : 'fa-chevron-left'
|
25
|
+
when 'gamma'
|
26
|
+
state == 'collapsed' ? 'fa-chevron-left' : 'fa-chevron-right'
|
27
|
+
when 'delta'
|
28
|
+
state == 'collapsed' ? 'fa-chevron-up' : 'fa-chevron-down'
|
29
|
+
else
|
30
|
+
''
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def default_step_progress
|
35
|
+
['Thinking']
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -2,98 +2,72 @@
|
|
2
2
|
|
3
3
|
module MetaWorkflows
|
4
4
|
module MetaWorkflowsHelper
|
5
|
-
|
6
|
-
|
5
|
+
include MetaWorkflows::FrameIdHelper
|
6
|
+
include MetaWorkflows::PartialPathsHelper
|
7
|
+
include MetaWorkflows::UiStateHelper
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
return "#{base_id}_structured_input" if options[:structured_input]
|
11
|
-
return "#{base_id}_chat_history" if options[:chat_history]
|
12
|
-
return "#{base_id}_streaming" if options[:streaming]
|
13
|
-
|
14
|
-
base_id
|
15
|
-
end
|
16
|
-
|
17
|
-
def turbo_stream_name(record)
|
18
|
-
[record.class.name.downcase, record.id]
|
19
|
-
end
|
20
|
-
|
21
|
-
def meta_loader_message
|
22
|
-
'meta_workflows/loader_message'
|
23
|
-
end
|
24
|
-
|
25
|
-
def meta_error_message
|
26
|
-
'meta_workflows/error_message'
|
27
|
-
end
|
28
|
-
|
29
|
-
def meta_response_form
|
30
|
-
'meta_workflows/response_form_lexi'
|
31
|
-
end
|
32
|
-
|
33
|
-
def meta_structured_input
|
34
|
-
'meta_workflows/structured_input'
|
9
|
+
def current_step_has_repetitions?(workflow_execution)
|
10
|
+
workflow_execution.step_repetitions(workflow_execution.current_step).present?
|
35
11
|
end
|
36
12
|
|
37
|
-
def
|
38
|
-
|
39
|
-
end
|
13
|
+
def show_next_button?(workflow_execution)
|
14
|
+
return false if current_step_has_repetitions?(workflow_execution)
|
40
15
|
|
41
|
-
|
42
|
-
'meta_workflows/chat_history'
|
16
|
+
workflow_execution.step_advanceable?(workflow_execution.current_step)
|
43
17
|
end
|
44
18
|
|
45
|
-
def
|
46
|
-
|
47
|
-
end
|
19
|
+
def show_skip_button?(workflow_execution)
|
20
|
+
return false if current_step_has_repetitions?(workflow_execution)
|
48
21
|
|
49
|
-
|
50
|
-
'meta_workflows/redirect'
|
22
|
+
workflow_execution.step_skippable?(workflow_execution.current_step)
|
51
23
|
end
|
52
24
|
|
53
|
-
def
|
54
|
-
'
|
25
|
+
def default_step_progress
|
26
|
+
['Thinking']
|
55
27
|
end
|
56
28
|
|
57
|
-
def
|
58
|
-
|
59
|
-
end
|
29
|
+
def show_structured_input?(local_assigns, structured_input_config)
|
30
|
+
current_step = local_assigns[:current_step]
|
60
31
|
|
61
|
-
|
62
|
-
|
32
|
+
(structured_input_config.present? && !local_assigns[:initial_load]) ||
|
33
|
+
(local_assigns[:initial_load] && !current_step&.initial_execution?)
|
63
34
|
end
|
64
35
|
|
65
|
-
def
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
state == 'collapsed' ? 'fa-chevron-left' : 'fa-chevron-right'
|
72
|
-
when 'delta'
|
73
|
-
state == 'collapsed' ? 'fa-chevron-up' : 'fa-chevron-down'
|
36
|
+
def current_step_and_config(active_execution, step_structured_input_config)
|
37
|
+
if active_execution.present?
|
38
|
+
[
|
39
|
+
active_execution.workflow_steps.order(:step).last,
|
40
|
+
step_structured_input_config
|
41
|
+
]
|
74
42
|
else
|
75
|
-
|
43
|
+
[nil, {}]
|
76
44
|
end
|
77
45
|
end
|
78
46
|
|
79
|
-
|
80
|
-
|
47
|
+
# Consolidates all data fetching for the Lexi chat tray using service object
|
48
|
+
def lexi_chat_data(record)
|
49
|
+
LexiChatDataService.new(record).call
|
81
50
|
end
|
82
51
|
|
83
|
-
def
|
84
|
-
|
85
|
-
|
86
|
-
workflow_execution.step_advanceable?(workflow_execution.current_step)
|
52
|
+
def structured_form_url(workflow_execution)
|
53
|
+
workflow_execution ? meta_workflows.structured_human_path(workflow_execution.id) : '#'
|
87
54
|
end
|
88
55
|
|
89
|
-
def
|
90
|
-
|
91
|
-
|
92
|
-
workflow_execution.step_skippable?(workflow_execution.current_step)
|
56
|
+
def structured_chat_id(local_assigns)
|
57
|
+
local_assigns[:chat_id] || local_assigns[:current_step]&.chat&.id
|
93
58
|
end
|
94
59
|
|
95
|
-
|
96
|
-
|
60
|
+
# Common locals for lexi chat input area
|
61
|
+
def lexi_chat_input_locals(record, chat_data, wrapper_class)
|
62
|
+
{
|
63
|
+
record: record,
|
64
|
+
workflow_execution: chat_data[:active_execution],
|
65
|
+
current_step: chat_data[:current_step],
|
66
|
+
structured_input_config: chat_data[:structured_input_config],
|
67
|
+
chat_id: chat_data[:active_chat]&.id,
|
68
|
+
is_structured_input: chat_data[:is_structured_input],
|
69
|
+
wrapper_class: wrapper_class
|
70
|
+
}
|
97
71
|
end
|
98
72
|
end
|
99
73
|
end
|
@@ -57,8 +57,9 @@ module MetaWorkflows
|
|
57
57
|
locals: {
|
58
58
|
record: record,
|
59
59
|
chat_id: chat.id,
|
60
|
-
|
61
|
-
|
60
|
+
workflow_execution: workflow_execution,
|
61
|
+
current_step: workflow_execution.workflow_steps&.order(:step)&.last,
|
62
|
+
structured_input_config: structured_input_config
|
62
63
|
}
|
63
64
|
)
|
64
65
|
end
|
@@ -21,5 +21,15 @@ module MetaWorkflows
|
|
21
21
|
def increment_step
|
22
22
|
update(current_step: current_step + 1)
|
23
23
|
end
|
24
|
+
|
25
|
+
# Get the latest workflow step with its chat (optimized for preloaded data)
|
26
|
+
def latest_workflow_step
|
27
|
+
workflow_steps.max_by(&:step)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Get the chat from the latest step (optimized for preloaded data)
|
31
|
+
def latest_chat
|
32
|
+
latest_workflow_step&.chat
|
33
|
+
end
|
24
34
|
end
|
25
35
|
end
|
@@ -11,10 +11,18 @@ module MetaWorkflows
|
|
11
11
|
|
12
12
|
has_one :workflow, through: :workflow_execution, class_name: 'MetaWorkflows::Workflow'
|
13
13
|
|
14
|
+
# Callbacks
|
15
|
+
before_save :mark_execution_started_if_chat_assigned
|
16
|
+
|
14
17
|
# Scopes for error handling
|
15
18
|
scope :with_errors, -> { where.not(error_message: nil) }
|
16
19
|
scope :without_errors, -> { where(error_message: nil) }
|
17
20
|
|
21
|
+
# Initial execution methods
|
22
|
+
def initial_execution?
|
23
|
+
initial_execution
|
24
|
+
end
|
25
|
+
|
18
26
|
# Error handling methods
|
19
27
|
def error?
|
20
28
|
error_message.present?
|
@@ -57,5 +65,13 @@ module MetaWorkflows
|
|
57
65
|
update!(repetition: new_repetition)
|
58
66
|
new_repetition
|
59
67
|
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def mark_execution_started_if_chat_assigned
|
72
|
+
return unless chat_id_changed? && chat_id.present? && initial_execution?
|
73
|
+
|
74
|
+
self.initial_execution = false
|
75
|
+
end
|
60
76
|
end
|
61
77
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MetaWorkflows
|
4
|
+
class LexiChatDataService < ApplicationService
|
5
|
+
def initialize(record)
|
6
|
+
super()
|
7
|
+
@record = record
|
8
|
+
end
|
9
|
+
|
10
|
+
def call
|
11
|
+
executions = @record&.workflow_executions
|
12
|
+
active_execution = executions&.order(created_at: :desc)&.first
|
13
|
+
|
14
|
+
if active_execution
|
15
|
+
build_active_execution_data(active_execution)
|
16
|
+
else
|
17
|
+
build_empty_data
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :record
|
24
|
+
|
25
|
+
def build_active_execution_data(active_execution)
|
26
|
+
current_step = active_execution.latest_workflow_step
|
27
|
+
active_chat = active_execution.latest_chat
|
28
|
+
chat_history = active_execution.execution_chat_history
|
29
|
+
current_step_data = active_execution.step_data(active_execution.current_step)
|
30
|
+
step_structured_input_config = current_step_data&.dig('structured_input')
|
31
|
+
is_structured_input = step_structured_input_config.present? &&
|
32
|
+
current_step_data&.dig('action') == 'structured_human'
|
33
|
+
|
34
|
+
{
|
35
|
+
active_execution: active_execution,
|
36
|
+
current_step: current_step,
|
37
|
+
active_chat: active_chat,
|
38
|
+
chat_history: chat_history,
|
39
|
+
current_step_data: current_step_data,
|
40
|
+
step_structured_input_config: step_structured_input_config,
|
41
|
+
is_structured_input: is_structured_input,
|
42
|
+
structured_input_config: step_structured_input_config || {}
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
def build_empty_data
|
47
|
+
{
|
48
|
+
active_execution: nil,
|
49
|
+
current_step: nil,
|
50
|
+
active_chat: nil,
|
51
|
+
chat_history: nil,
|
52
|
+
current_step_data: nil,
|
53
|
+
step_structured_input_config: nil,
|
54
|
+
is_structured_input: false,
|
55
|
+
structured_input_config: {}
|
56
|
+
}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -12,6 +12,7 @@
|
|
12
12
|
value="<%= option['value'] %>"
|
13
13
|
class="structured-checkbox-input"
|
14
14
|
data-meta-workflows--structured-form-submit-target="checkbox"
|
15
|
+
data-meta-workflows--lexi-form-submit-target="structuredInput"
|
15
16
|
data-action="change->meta-workflows--structured-form-submit#handleCheckboxChange"
|
16
17
|
aria-describedby="structured-checkbox-help"
|
17
18
|
>
|
@@ -22,19 +23,4 @@
|
|
22
23
|
<% end %>
|
23
24
|
</div>
|
24
25
|
<div id="structured-checkbox-help" class="sr-only">Use space to select/deselect options</div>
|
25
|
-
|
26
|
-
<div class="structured-submit-container">
|
27
|
-
<button
|
28
|
-
type="submit"
|
29
|
-
class="structured-submit-button"
|
30
|
-
data-meta-workflows--structured-form-submit-target="submitButton"
|
31
|
-
data-action="click->meta-workflows--structured-form-submit#handleCheckboxSubmit"
|
32
|
-
disabled
|
33
|
-
aria-describedby="structured-submit-help"
|
34
|
-
aria-label="Submit your selections"
|
35
|
-
>
|
36
|
-
<i class="fa-solid fa-arrow-up"></i>
|
37
|
-
</button>
|
38
|
-
<div id="structured-submit-help" class="sr-only">Submit your selections. Button is disabled until at least one option is selected.</div>
|
39
|
-
</div>
|
40
26
|
</div>
|
@@ -1,10 +1,5 @@
|
|
1
1
|
<%# Lexi Chat Alpha Tray (Center Display) %>
|
2
|
-
<%
|
3
|
-
<% active_chat = active_execution&.workflow_steps&.last&.chat %>
|
4
|
-
<% chat_history = active_execution&.execution_chat_history %>
|
5
|
-
<% current_step_data = active_execution&.step_data(active_execution&.current_step) %>
|
6
|
-
<% step_structured_input_config = current_step_data&.dig('structured_input') %>
|
7
|
-
<% is_structured_input = step_structured_input_config.present? && current_step_data&.dig('action') == 'structured_human' %>
|
2
|
+
<% chat_data = lexi_chat_data(local_assigns[:record]) %>
|
8
3
|
|
9
4
|
|
10
5
|
<div class="lexi-chat-alpha-tray">
|
@@ -31,30 +26,15 @@
|
|
31
26
|
<%# Right column - Chat and Input %>
|
32
27
|
<div class="lexi-chat-alpha-right-column">
|
33
28
|
<%# Scrollable chat messages area %>
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
show_loader: false,
|
40
|
-
show_error: false,
|
41
|
-
step_progress: nil,
|
42
|
-
full_response: nil,
|
43
|
-
error_message: nil
|
44
|
-
} %>
|
45
|
-
</div>
|
29
|
+
<%= render partial: meta_lexi_chat_messages, locals: {
|
30
|
+
record: local_assigns[:record],
|
31
|
+
chat_history: chat_data[:chat_history],
|
32
|
+
container_class: 'lexi-chat-alpha-messages'
|
33
|
+
} %>
|
46
34
|
|
47
35
|
<%# Input area (fixed at bottom) %>
|
48
36
|
<div class="lexi-chat-alpha-input-area">
|
49
|
-
|
50
|
-
<!-- Structured Input (always rendered, conditionally displays content) -->
|
51
|
-
<%= render meta_structured_input, record: local_assigns[:record], structured_input_config: false, is_structured_input: false %>
|
52
|
-
|
53
|
-
<!-- Regular Form Input (always present) -->
|
54
|
-
<%= render partial: meta_response_form, locals: {record: local_assigns[:record], response_enabled: true,
|
55
|
-
workflow_execution_id: active_execution&.id, chat_id: active_execution&.workflow_steps&.last&.chat&.id,
|
56
|
-
workflow_execution: active_execution, is_structured_input: is_structured_input, show_skip_button: false, show_next_button: false } %>
|
57
|
-
</div>
|
37
|
+
<%= render partial: meta_lexi_chat_input_area, locals: lexi_chat_input_locals(local_assigns[:record], chat_data, 'lexi-chat-alpha-input-container') %>
|
58
38
|
</div>
|
59
39
|
</div>
|
60
40
|
</div>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<%# Shared input area %>
|
2
|
+
<div class="<%= local_assigns[:wrapper_class] || 'lexi-input-wrapper' %>" data-controller="meta-workflows--lexi-form-submit">
|
3
|
+
<%= render meta_structured_input,
|
4
|
+
record: local_assigns[:record],
|
5
|
+
workflow_execution: local_assigns[:workflow_execution],
|
6
|
+
current_step: local_assigns[:current_step],
|
7
|
+
structured_input_config: local_assigns[:structured_input_config],
|
8
|
+
initial_load: true %>
|
9
|
+
|
10
|
+
<%= render partial: meta_response_form, locals: {
|
11
|
+
record: local_assigns[:record],
|
12
|
+
response_enabled: true,
|
13
|
+
workflow_execution_id: local_assigns[:workflow_execution]&.id,
|
14
|
+
chat_id: local_assigns[:chat_id],
|
15
|
+
step_has_repetitions: true,
|
16
|
+
is_structured_input: local_assigns[:is_structured_input],
|
17
|
+
show_skip_button: false,
|
18
|
+
show_next_button: false
|
19
|
+
} %>
|
20
|
+
</div>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<%# Shared chat messages area %>
|
2
|
+
<div id="main-scroll-container" class="<%= local_assigns[:container_class] || 'lexi-chat-messages' %>">
|
3
|
+
<%= render partial: meta_response, locals: {
|
4
|
+
record: local_assigns[:record],
|
5
|
+
chat_history: local_assigns[:chat_history],
|
6
|
+
current_user_messages: [],
|
7
|
+
show_loader: false,
|
8
|
+
show_error: false,
|
9
|
+
step_progress: nil,
|
10
|
+
full_response: nil,
|
11
|
+
error_message: nil
|
12
|
+
} %>
|
13
|
+
</div>
|
@@ -1,10 +1,6 @@
|
|
1
|
-
<%# Lexi Chat Tray %>
|
2
|
-
<%
|
3
|
-
|
4
|
-
<% chat_history = active_execution&.execution_chat_history %>
|
5
|
-
<% current_step_data = active_execution&.step_data(active_execution&.current_step) %>
|
6
|
-
<% step_structured_input_config = current_step_data&.dig('structured_input') %>
|
7
|
-
<% is_structured_input = step_structured_input_config.present? && current_step_data&.dig('action') == 'structured_human' %>
|
1
|
+
<%# Lexi Chat Tray (Right Side) %>
|
2
|
+
<% chat_data = lexi_chat_data(local_assigns[:record]) %>
|
3
|
+
|
8
4
|
|
9
5
|
<div class="lexi-chat-tray lexi-chat-container-full">
|
10
6
|
<!-- Header with Lexi logo and action icons -->
|
@@ -23,27 +19,20 @@
|
|
23
19
|
</div>
|
24
20
|
|
25
21
|
<!-- Chat messages area -->
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
error_message: nil
|
36
|
-
} %>
|
22
|
+
<%= render partial: meta_lexi_chat_messages, locals: {
|
23
|
+
record: local_assigns[:record],
|
24
|
+
chat_history: chat_data[:chat_history],
|
25
|
+
container_class: 'lexi-chat-messages'
|
26
|
+
} %>
|
27
|
+
|
28
|
+
<!-- Structured inputs area (above avatar) -->
|
29
|
+
<div class="structured-input-area" data-controller="meta-workflows--lexi-form-submit">
|
30
|
+
<%= render meta_structured_input, record: local_assigns[:record], structured_input_config: false, is_structured_input: false %>
|
37
31
|
</div>
|
38
32
|
|
39
33
|
<!-- Avatar and input area pinned to bottom -->
|
40
34
|
<div class="lexi-chat-bottom">
|
41
35
|
<%= image_tag("lexi-expanded.png", alt: "Lexi Avatar", class: "lexi-avatar") %>
|
42
|
-
|
43
|
-
<%= render meta_structured_input, record: local_assigns[:record], structured_input_config: false, is_structured_input: false %>
|
44
|
-
|
45
|
-
<%= render partial: meta_response_form, locals: {record: local_assigns[:record], response_enabled: true, workflow_execution_id: active_execution&.id,
|
46
|
-
chat_id: active_execution&.workflow_steps&.last&.chat&.id, workflow_execution: active_execution, is_structured_input: is_structured_input } %>
|
47
|
-
</div>
|
36
|
+
<%= render partial: meta_lexi_chat_input_area, locals: lexi_chat_input_locals(local_assigns[:record], chat_data, 'lexi-input-wrapper') %>
|
48
37
|
</div>
|
49
38
|
</div>
|
@@ -12,6 +12,7 @@
|
|
12
12
|
name="single_choice_selection"
|
13
13
|
value="<%= option['value'] %>"
|
14
14
|
class="structured-radio-input"
|
15
|
+
data-meta-workflows--lexi-form-submit-target="structuredInput"
|
15
16
|
data-action="change->meta-workflows--structured-form-submit#handleSubmit"
|
16
17
|
aria-describedby="structured-radio-help"
|
17
18
|
required
|
@@ -19,6 +19,7 @@
|
|
19
19
|
value="<%= options['min']['value'] %>"
|
20
20
|
class="structured-slider-input"
|
21
21
|
data-meta-workflows--structured-form-submit-target="slider"
|
22
|
+
data-meta-workflows--lexi-form-submit-target="structuredInput"
|
22
23
|
data-action="change->meta-workflows--structured-form-submit#handleSubmit input->meta-workflows--structured-form-submit#handleSliderChange"
|
23
24
|
aria-describedby="structured-slider-help"
|
24
25
|
aria-valuemin="<%= options['min']['value'] %>"
|
@@ -1,13 +1,8 @@
|
|
1
1
|
<%= turbo_frame_tag target_frame_id(record, structured_input: true) do %>
|
2
|
-
|
3
|
-
|
4
|
-
# Get workflow execution for form submission
|
5
|
-
workflow_execution = record.workflow_executions.order(created_at: :desc).first
|
6
|
-
form_url = workflow_execution ? meta_workflows.structured_human_path(workflow_execution.id) : "#"
|
7
|
-
chat_id = local_assigns[:chat_id] || workflow_execution&.workflow_steps&.last&.chat&.id
|
8
|
-
%>
|
2
|
+
|
3
|
+
<% if show_structured_input?(local_assigns, structured_input_config) %>
|
9
4
|
|
10
|
-
<%= form_with url:
|
5
|
+
<%= form_with url: structured_form_url(local_assigns[:workflow_execution]),
|
11
6
|
method: :patch,
|
12
7
|
id: "#{target_frame_id(record, structured_input: true)}_form",
|
13
8
|
data: {
|
@@ -15,7 +10,7 @@
|
|
15
10
|
"meta-workflows--structured-form-submit-target": "form",
|
16
11
|
"meta-workflows--lexi-form-submit-target": "structuredInputForm"
|
17
12
|
} do |form| %>
|
18
|
-
<%= form.hidden_field :chat_id, value:
|
13
|
+
<%= form.hidden_field :chat_id, value: structured_chat_id(local_assigns) %>
|
19
14
|
|
20
15
|
<div class="structured-input-wrapper">
|
21
16
|
<% case structured_input_config['type'] %>
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module MetaWorkflows
|
4
4
|
MAJOR = 0
|
5
5
|
MINOR = 9
|
6
|
-
PATCH =
|
6
|
+
PATCH = 33 # this is automatically incremented by the build process
|
7
7
|
|
8
8
|
VERSION = "#{MetaWorkflows::MAJOR}.#{MetaWorkflows::MINOR}.#{MetaWorkflows::PATCH}".freeze
|
9
9
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: meta_workflows
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.33
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Leonid Medovyy
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2025-07-
|
12
|
+
date: 2025-07-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -138,6 +138,9 @@ files:
|
|
138
138
|
- app/controllers/meta_workflows/meta_controller.rb
|
139
139
|
- app/controllers/meta_workflows/structured_humans_controller.rb
|
140
140
|
- app/controllers/meta_workflows/workflow_imports_controller.rb
|
141
|
+
- app/helpers/concerns/meta_workflows/frame_id_helper.rb
|
142
|
+
- app/helpers/concerns/meta_workflows/partial_paths_helper.rb
|
143
|
+
- app/helpers/concerns/meta_workflows/ui_state_helper.rb
|
141
144
|
- app/helpers/meta_workflows/application_helper.rb
|
142
145
|
- app/helpers/meta_workflows/debug_helper.rb
|
143
146
|
- app/helpers/meta_workflows/execution_helper.rb
|
@@ -164,6 +167,7 @@ files:
|
|
164
167
|
- app/models/meta_workflows/workflow_step.rb
|
165
168
|
- app/services/meta_workflows/application_service.rb
|
166
169
|
- app/services/meta_workflows/execution_filter_service.rb
|
170
|
+
- app/services/meta_workflows/lexi_chat_data_service.rb
|
167
171
|
- app/services/meta_workflows/message_history_service.rb
|
168
172
|
- app/services/meta_workflows/workflow_import_service.rb
|
169
173
|
- app/sidekiq/meta_workflows/tools/meta_workflow_tool.rb
|
@@ -173,6 +177,8 @@ files:
|
|
173
177
|
- app/views/meta_workflows/_checkbox_input.html.erb
|
174
178
|
- app/views/meta_workflows/_error_message.html.erb
|
175
179
|
- app/views/meta_workflows/_lexi_chat_alpha_tray.html.erb
|
180
|
+
- app/views/meta_workflows/_lexi_chat_input_area.html.erb
|
181
|
+
- app/views/meta_workflows/_lexi_chat_messages.html.erb
|
176
182
|
- app/views/meta_workflows/_lexi_chat_right_tray.html.erb
|
177
183
|
- app/views/meta_workflows/_loader_message.html.erb
|
178
184
|
- app/views/meta_workflows/_radio_input.html.erb
|
@@ -201,6 +207,7 @@ files:
|
|
201
207
|
- db/migrate/20250626211926_add_repetition_to_meta_workflows_workflow_steps.rb
|
202
208
|
- db/migrate/20250709153017_add_recipe_to_meta_workflows_workflow_executions.rb
|
203
209
|
- db/migrate/20250714192853_create_meta_workflows_execution_chat_histories.rb
|
210
|
+
- db/migrate/20250721195735_add_initial_execution_to_meta_workflows_workflow_steps.rb
|
204
211
|
- lib/meta_workflows.rb
|
205
212
|
- lib/meta_workflows/asset_installer.rb
|
206
213
|
- lib/meta_workflows/configuration.rb
|