meta_workflows 0.9.24 → 0.9.25
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/README.md +73 -0
- data/app/assets/javascripts/meta_workflows/controllers/lexi_form_submit_controller.js +34 -7
- data/app/controllers/concerns/meta_workflows/streamable.rb +3 -1
- data/app/controllers/meta_workflows/meta_controller.rb +1 -1
- data/app/helpers/meta_workflows/meta_workflows_helper.rb +12 -0
- data/app/jobs/meta_workflows/human_input_job.rb +2 -0
- data/app/models/concerns/recipe_accessible.rb +8 -0
- data/app/views/meta_workflows/_lexi_chat_alpha_tray.html.erb +3 -1
- data/app/views/meta_workflows/_lexi_chat_right_tray.html.erb +2 -1
- data/app/views/meta_workflows/_response_form_lexi.html.erb +16 -6
- data/lib/meta_workflows/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 45d13fedf05d6e20b7070f2615acbc0b90e2e34a68b573213ef71e4383c7b6cb
|
4
|
+
data.tar.gz: 86344d2db4c7ad7b33549f030e3b3c6017d668e24597655b6b369b97456cbb54
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 182ebf3da42adc40c4e7808da4a2a030af63500b97fc1b3dabb350c6eb165706fcdf208135773053fce14facd398e2515d4457113f54c853fd7c80e3141fe5aa
|
7
|
+
data.tar.gz: e1d867b821e2d42c6a215e0c6bd7a810604c490efa51a1791f6e2a0449192cd4bc628b2a30ff6eaf7710288f702c9cc336fb3e4b09346a5492cbe6c5af12fd0a
|
data/README.md
CHANGED
@@ -67,6 +67,17 @@ MetaWorkflows supports several action types for different workflow needs:
|
|
67
67
|
- Requires `prompt_id` for context presentation
|
68
68
|
- Collects user feedback through forms
|
69
69
|
- Workflow pauses until human input is provided
|
70
|
+
- Supports `advanceable: true` to show "Next" button for manual step advancement
|
71
|
+
- **Note**: When `repetitions` is configured, advance/skip buttons are hidden and repetition logic takes precedence
|
72
|
+
|
73
|
+
### `structured_human`
|
74
|
+
- Presents structured input UI (radio buttons, checkboxes, sliders) for user interaction
|
75
|
+
- Requires `prompt_id` for context presentation
|
76
|
+
- Collects structured user input through form elements
|
77
|
+
- Automatically advances to next step upon form submission
|
78
|
+
- Supports `skippable: true` to show "Skip" button for bypassing the step
|
79
|
+
- When `skippable` is present and clicked, a default user message will be sent 'Not mentioned' to notify the llm that the user did not answer whatever was being prompted
|
80
|
+
- **Note**: When `repetitions` is configured, skip buttons are hidden and repetition logic takes precedence
|
70
81
|
|
71
82
|
### `collection_create`
|
72
83
|
- Creates collections of related records atomically
|
@@ -85,6 +96,68 @@ MetaWorkflows supports several action types for different workflow needs:
|
|
85
96
|
- Marks workflow as complete
|
86
97
|
- Requires `redirect_path` or `redirect_method` configuration
|
87
98
|
|
99
|
+
## Workflow Step Behavior and Restrictions
|
100
|
+
|
101
|
+
### Step Advancement Controls
|
102
|
+
|
103
|
+
MetaWorkflows provides fine-grained control over how users can advance through workflow steps:
|
104
|
+
|
105
|
+
#### `advanceable` (Human Steps Only)
|
106
|
+
- **Purpose**: Adds a "Next" button to `human` action steps for manual advancement
|
107
|
+
- **Usage**: Add `advanceable: true` to a `human` step configuration
|
108
|
+
- **Behavior**: Users can click "Next" to advance without providing input
|
109
|
+
- **Restriction**: **Not available when `repetitions` is configured** - repetition logic takes precedence
|
110
|
+
|
111
|
+
#### `skippable` (Structured Human Steps Only)
|
112
|
+
- **Purpose**: Adds a "Skip" button to `structured_human` action steps
|
113
|
+
- **Usage**: Add `skippable: true` to a `structured_human` step configuration
|
114
|
+
- **Behavior**: Users can skip the structured input and advance to the next step
|
115
|
+
- **Restriction**: **Not available when `repetitions` is configured** - repetition logic takes precedence
|
116
|
+
|
117
|
+
#### `repetitions`
|
118
|
+
- **Purpose**: Allows a step to repeat a specified number of times before advancing
|
119
|
+
- **Usage**: Add `repetitions: <number>` to any step configuration
|
120
|
+
- **Behavior**: Step will repeat until the specified count is reached, then auto-advance
|
121
|
+
- **Priority**: **Takes precedence over `advanceable` and `skippable`** - advance/skip buttons are hidden
|
122
|
+
|
123
|
+
### Configuration Examples
|
124
|
+
|
125
|
+
```yaml
|
126
|
+
# Human step with advance button (when no repetitions)
|
127
|
+
- name: "review_content"
|
128
|
+
action: "human"
|
129
|
+
prompt_id: "content_review"
|
130
|
+
advanceable: true
|
131
|
+
|
132
|
+
# Structured human step with skip button (when no repetitions)
|
133
|
+
- name: "optional_survey"
|
134
|
+
action: "structured_human"
|
135
|
+
prompt_id: "user_survey"
|
136
|
+
skippable: true
|
137
|
+
structured_input:
|
138
|
+
type: single_choice
|
139
|
+
options:
|
140
|
+
- label: "Option A"
|
141
|
+
value: "a"
|
142
|
+
|
143
|
+
# Step with repetitions (advance/skip buttons hidden)
|
144
|
+
- name: "retry_process"
|
145
|
+
action: "agent"
|
146
|
+
prompt_id: "processing_task"
|
147
|
+
repetitions: 3 # Will repeat 3 times before advancing
|
148
|
+
```
|
149
|
+
|
150
|
+
### Behavioral Rules
|
151
|
+
|
152
|
+
1. **Repetitions Take Precedence**: When `repetitions` is configured on a step, advance and skip buttons are automatically hidden regardless of `advanceable` or `skippable` settings
|
153
|
+
2. **Action Type Restrictions**:
|
154
|
+
- `advanceable` only applies to `human` action steps
|
155
|
+
- `skippable` only applies to `structured_human` action steps
|
156
|
+
3. **Automatic vs Manual Advancement**:
|
157
|
+
- Steps with `repetitions` advance automatically after reaching the repeat count
|
158
|
+
- Steps with `advanceable`/`skippable` require user interaction to advance
|
159
|
+
- All other steps advance based on their action type's default behavior
|
160
|
+
|
88
161
|
## Model Configuration
|
89
162
|
|
90
163
|
MetaWorkflows supports configuring different AI models for different workflow steps, allowing you to optimize performance and cost by using the most appropriate model for each task.
|
@@ -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', '
|
4
|
+
static targets = ['textarea', 'form', 'structuredInputForm', 'hiddenMessage'];
|
5
5
|
|
6
6
|
connect() {
|
7
7
|
this.submitted = false;
|
@@ -13,16 +13,13 @@ export default class extends Controller {
|
|
13
13
|
|
14
14
|
handleKeyDown(event) {
|
15
15
|
if (event.key === 'Enter' && !event.shiftKey) {
|
16
|
-
this.handleSubmit(event);
|
17
|
-
}
|
18
|
-
}
|
19
|
-
|
20
|
-
handleSubmit(event) {
|
21
|
-
if (event) {
|
22
16
|
event.preventDefault();
|
23
17
|
event.stopPropagation();
|
18
|
+
this.handleSubmit();
|
24
19
|
}
|
20
|
+
}
|
25
21
|
|
22
|
+
handleSubmit(event) {
|
26
23
|
if (this.submitted) {
|
27
24
|
return;
|
28
25
|
}
|
@@ -32,6 +29,28 @@ export default class extends Controller {
|
|
32
29
|
}
|
33
30
|
|
34
31
|
this.submitted = true;
|
32
|
+
|
33
|
+
if (this.hasHiddenMessageTarget) {
|
34
|
+
this.hiddenMessageTarget.disabled = true;
|
35
|
+
}
|
36
|
+
|
37
|
+
this.hideStructuredInputForm();
|
38
|
+
this.formTarget.requestSubmit();
|
39
|
+
}
|
40
|
+
|
41
|
+
handleSkip(event) {
|
42
|
+
event.preventDefault();
|
43
|
+
|
44
|
+
if (this.submitted) {
|
45
|
+
return;
|
46
|
+
}
|
47
|
+
|
48
|
+
this.submitted = true;
|
49
|
+
|
50
|
+
if (this.hasTextareaTarget) {
|
51
|
+
this.textareaTarget.disabled = true;
|
52
|
+
}
|
53
|
+
|
35
54
|
this.hideStructuredInputForm();
|
36
55
|
this.formTarget.requestSubmit();
|
37
56
|
}
|
@@ -39,6 +58,14 @@ export default class extends Controller {
|
|
39
58
|
hideStructuredInputForm() {
|
40
59
|
if (this.hasStructuredInputFormTarget) {
|
41
60
|
this.structuredInputFormTarget.style.display = 'none';
|
61
|
+
return;
|
62
|
+
}
|
63
|
+
|
64
|
+
const structuredForm = document.querySelector('[data-meta-workflows--lexi-form-submit-target="structuredInputForm"]');
|
65
|
+
if (structuredForm) {
|
66
|
+
structuredForm.style.display = 'none';
|
67
|
+
return;
|
42
68
|
}
|
43
69
|
}
|
44
70
|
}
|
71
|
+
|
@@ -57,7 +57,9 @@ module MetaWorkflows
|
|
57
57
|
chat_id: chat_id,
|
58
58
|
response_enabled: response_enabled,
|
59
59
|
responding: responding,
|
60
|
-
step_has_repetitions: current_step_has_repetitions?(workflow_execution)
|
60
|
+
step_has_repetitions: current_step_has_repetitions?(workflow_execution),
|
61
|
+
show_next_button: show_next_button?(workflow_execution),
|
62
|
+
show_skip_button: show_skip_button?(workflow_execution)
|
61
63
|
}
|
62
64
|
end
|
63
65
|
|
@@ -49,7 +49,7 @@ module MetaWorkflows
|
|
49
49
|
build_chat_history_stream(record: @record, workflow_execution: @workflow_execution),
|
50
50
|
build_streaming_response_stream(record: @record, show_loader: true),
|
51
51
|
build_response_form_stream(record: @record, workflow_execution: @workflow_execution,
|
52
|
-
response_enabled: false, responding:
|
52
|
+
response_enabled: false, responding: true, chat_id: params[:chat_id])
|
53
53
|
]
|
54
54
|
end
|
55
55
|
end
|
@@ -91,6 +91,18 @@ module MetaWorkflows
|
|
91
91
|
workflow_execution.step_repetitions(workflow_execution.current_step).present?
|
92
92
|
end
|
93
93
|
|
94
|
+
def show_next_button?(workflow_execution)
|
95
|
+
return false if current_step_has_repetitions?(workflow_execution)
|
96
|
+
|
97
|
+
workflow_execution.step_advanceable?(workflow_execution.current_step)
|
98
|
+
end
|
99
|
+
|
100
|
+
def show_skip_button?(workflow_execution)
|
101
|
+
return false if current_step_has_repetitions?(workflow_execution)
|
102
|
+
|
103
|
+
workflow_execution.step_skippable?(workflow_execution.current_step)
|
104
|
+
end
|
105
|
+
|
94
106
|
def default_step_progress
|
95
107
|
['Thinking']
|
96
108
|
end
|
@@ -43,6 +43,8 @@ module MetaWorkflows
|
|
43
43
|
response_enabled: true,
|
44
44
|
chat_id: chat.id,
|
45
45
|
step_has_repetitions: current_step_has_repetitions?(workflow_execution),
|
46
|
+
show_next_button: show_next_button?(workflow_execution),
|
47
|
+
show_skip_button: show_skip_button?(workflow_execution),
|
46
48
|
is_structured_input: is_structured_input }
|
47
49
|
)
|
48
50
|
end
|
@@ -23,6 +23,14 @@ module RecipeAccessible
|
|
23
23
|
recipe&.dig('steps', step, 'repetitions')
|
24
24
|
end
|
25
25
|
|
26
|
+
def step_advanceable?(step)
|
27
|
+
recipe&.dig('steps', step, 'advanceable') || false
|
28
|
+
end
|
29
|
+
|
30
|
+
def step_skippable?(step)
|
31
|
+
recipe&.dig('steps', step, 'skippable') || false
|
32
|
+
end
|
33
|
+
|
26
34
|
def total_steps
|
27
35
|
recipe&.dig('steps')&.size || 0
|
28
36
|
end
|
@@ -51,7 +51,9 @@
|
|
51
51
|
<%= render meta_structured_input, record: local_assigns[:record], structured_input_config: false, is_structured_input: false %>
|
52
52
|
|
53
53
|
<!-- Regular Form Input (always present) -->
|
54
|
-
<%= render partial: meta_response_form, locals: {record: local_assigns[:record], response_enabled: true,
|
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 } %>
|
55
57
|
</div>
|
56
58
|
</div>
|
57
59
|
</div>
|
@@ -42,7 +42,8 @@
|
|
42
42
|
<div class="lexi-input-wrapper" data-controller="meta-workflows--lexi-form-submit">
|
43
43
|
<%= render meta_structured_input, record: local_assigns[:record], structured_input_config: false, is_structured_input: false %>
|
44
44
|
|
45
|
-
<%= render partial: meta_response_form, locals: {record: local_assigns[:record], response_enabled: true, workflow_execution_id: active_execution&.id,
|
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 } %>
|
46
47
|
</div>
|
47
48
|
</div>
|
48
49
|
</div>
|
@@ -8,7 +8,6 @@
|
|
8
8
|
<% if local_assigns[:is_structured_input] %>
|
9
9
|
<%= form.hidden_field :auto_advance, value: true %>
|
10
10
|
<% end %>
|
11
|
-
<fieldset></fieldset>
|
12
11
|
<div class="lexi-form-container">
|
13
12
|
<!-- Input Container -->
|
14
13
|
<div class="lexi-input-container lexi-input-max-height">
|
@@ -36,7 +35,7 @@
|
|
36
35
|
<i class="fa-solid fa-arrow-up text-lg"></i>
|
37
36
|
</button>
|
38
37
|
<% else %>
|
39
|
-
<%= form.button type: "
|
38
|
+
<%= form.button type: "button", class: "lexi-send-button sm-btn sm-btn-primary", data: { "meta-workflows--lexi-form-submit-target": "submitButton", action: "click->meta-workflows--lexi-form-submit#handleSubmit" } do %>
|
40
39
|
<i class="fa-solid fa-arrow-up text-lg"></i>
|
41
40
|
<% end %>
|
42
41
|
<% end %>
|
@@ -47,13 +46,24 @@
|
|
47
46
|
<p class="lexi-recording-notice">This chat is being recorded.</p>
|
48
47
|
|
49
48
|
<div>
|
50
|
-
<%
|
51
|
-
|
52
|
-
|
53
|
-
<% else %>
|
49
|
+
<% workflow_execution = local_assigns[:workflow_execution] %>
|
50
|
+
<% if workflow_execution && show_next_button?(workflow_execution) || local_assigns[:show_next_button] %>
|
51
|
+
<!-- Next button for advanceable steps -->
|
54
52
|
<%= form.button type: "submit", name: "manual_advance", value: "true", class: "lexi-advance-button #{'opacity-50 cursor-not-allowed' if local_assigns[:responding]}", disabled: local_assigns[:responding], data: { "meta-workflows--lexi-form-submit-target": "submitButton", action: "click->meta-workflows--lexi-form-submit#handleSubmit" } do %>
|
55
53
|
<i class="fa-light fa-arrow-right"></i> Next
|
56
54
|
<% end %>
|
55
|
+
<% elsif workflow_execution && show_skip_button?(workflow_execution) || local_assigns[:show_skip_button] %>
|
56
|
+
<!-- Skip button for skippable steps -->
|
57
|
+
<%= form.button type: "submit", name: "auto_advance", value: true, class: "lexi-advance-button #{'opacity-50 cursor-not-allowed' if local_assigns[:responding]}", disabled: local_assigns[:responding], data: { action: "click->meta-workflows--lexi-form-submit#handleSkip" } do %>
|
58
|
+
<i class="fa-light fa-forward-step"></i> Skip
|
59
|
+
<% end %>
|
60
|
+
<%= form.hidden_field :message, value: "Not Mentioned", data: { "meta-workflows--lexi-form-submit-target": "hiddenMessage" } %>
|
61
|
+
<% elsif local_assigns[:step_has_repetitions] %>
|
62
|
+
<!-- Empty placeholder to prevent layout jank for repetitions -->
|
63
|
+
<div aria-hidden="true"></div>
|
64
|
+
<% else %>
|
65
|
+
<!-- Empty placeholder for steps with no buttons -->
|
66
|
+
<div aria-hidden="true"></div>
|
57
67
|
<% end %>
|
58
68
|
</div>
|
59
69
|
</div>
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module MetaWorkflows
|
4
4
|
MAJOR = 0
|
5
5
|
MINOR = 9
|
6
|
-
PATCH =
|
6
|
+
PATCH = 25 # 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.25
|
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-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|