meta_workflows 0.9.7 → 0.9.8
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/controllers/meta_workflows/meta_controller.rb +4 -4
- data/app/helpers/meta_workflows/debug_helper.rb +3 -3
- data/app/helpers/meta_workflows/execution_helper.rb +3 -3
- data/app/helpers/meta_workflows/meta_workflows_helper.rb +1 -1
- data/app/models/meta_workflows/workflow.rb +0 -25
- data/app/models/meta_workflows/workflow_execution.rb +25 -0
- data/app/views/meta_workflows/debug/executions.html.erb +3 -3
- data/app/views/meta_workflows/debug/show_execution.html.erb +3 -3
- data/db/migrate/20250709153017_add_recipe_to_meta_workflows_workflow_executions.rb +5 -0
- data/lib/meta_workflows/version.rb +1 -1
- data/lib/services/meta_workflows/meta_workflow_service.rb +20 -19
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '08bc94e1aec754aadd106d9b6d5e4ec50e57d381ff25cc08f323666e7a56aff7'
|
4
|
+
data.tar.gz: 910ff3cba3a9cee0ce88bbea495b380a2b8c9a094d0d46d018985a6e06b98279
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 35629eb4037b1011c5d82ddc3618f24e7aa4956c4e59726e7ff441aba53a3f4b7695e83b83b1306a6fa0b35c9c18271a76c74d3fc27175cf3e6fbe05ebcccf4c
|
7
|
+
data.tar.gz: a283b0a86a6d1448727128a168b964cc3590493860a35146fb3875f22ee3bbc1acd87f5cac0342ca0c672af75037cfb910c6d1b4fe42d63dcf3fd1f57a4c116a
|
@@ -10,18 +10,18 @@ module MetaWorkflows
|
|
10
10
|
@record = @workflow_execution.record
|
11
11
|
@workflow = @workflow_execution.workflow
|
12
12
|
@workflow_step = @workflow_execution.workflow_steps.find_by(step: @workflow_execution.current_step)
|
13
|
-
@prompt_id = @
|
13
|
+
@prompt_id = @workflow_execution.prompt_id(@workflow_execution.current_step)
|
14
14
|
end
|
15
15
|
|
16
16
|
protected
|
17
17
|
|
18
18
|
def fetch_step_progress
|
19
|
-
@
|
20
|
-
|
19
|
+
@workflow_execution.step_progress(@workflow_execution.current_step) || ['Processing your request...',
|
20
|
+
'Talking to the LLM...']
|
21
21
|
end
|
22
22
|
|
23
23
|
def current_step_repetitions
|
24
|
-
@
|
24
|
+
@workflow_execution.step_repetitions(@workflow_execution.current_step)
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
@@ -26,9 +26,9 @@ module MetaWorkflows
|
|
26
26
|
class: 'cursor-help'
|
27
27
|
end
|
28
28
|
|
29
|
-
# Helper to safely get step data from workflow
|
30
|
-
def safe_step_data(
|
31
|
-
|
29
|
+
# Helper to safely get step data from workflow execution
|
30
|
+
def safe_step_data(workflow_execution, step_number)
|
31
|
+
workflow_execution.step_data(step_number)
|
32
32
|
rescue StandardError => e
|
33
33
|
{ 'error' => e.message }
|
34
34
|
end
|
@@ -4,16 +4,16 @@ module MetaWorkflows
|
|
4
4
|
module ExecutionHelper
|
5
5
|
# Helper to calculate execution progress percentage
|
6
6
|
def execution_progress_percentage(execution)
|
7
|
-
return 0 if execution.
|
7
|
+
return 0 if execution.total_steps.zero?
|
8
8
|
|
9
|
-
((execution.current_step.to_f / execution.
|
9
|
+
((execution.current_step.to_f / execution.total_steps) * 100).round(1)
|
10
10
|
rescue StandardError
|
11
11
|
0
|
12
12
|
end
|
13
13
|
|
14
14
|
# Helper to format execution progress display
|
15
15
|
def execution_progress_display(execution)
|
16
|
-
total_steps = execution.
|
16
|
+
total_steps = execution.total_steps
|
17
17
|
current_step = execution.current_step
|
18
18
|
percentage = execution_progress_percentage(execution)
|
19
19
|
|
@@ -65,7 +65,7 @@ module MetaWorkflows
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def current_step_has_repetitions?(workflow_execution)
|
68
|
-
workflow_execution.
|
68
|
+
workflow_execution.step_repetitions(workflow_execution.current_step).present?
|
69
69
|
end
|
70
70
|
end
|
71
71
|
end
|
@@ -6,31 +6,6 @@ module MetaWorkflows
|
|
6
6
|
validates :recipe, presence: true
|
7
7
|
|
8
8
|
has_many :workflow_executions, dependent: :destroy, class_name: 'MetaWorkflows::WorkflowExecution'
|
9
|
-
has_many :courses, through: :workflow_executions
|
10
9
|
has_many :workflow_steps, through: :workflow_executions, class_name: 'MetaWorkflows::WorkflowStep'
|
11
|
-
|
12
|
-
def step_progress(step)
|
13
|
-
recipe.dig('steps', step, 'step_progress')
|
14
|
-
end
|
15
|
-
|
16
|
-
def prompt_id(step)
|
17
|
-
recipe.dig('steps', step, 'prompt_id')
|
18
|
-
end
|
19
|
-
|
20
|
-
def step_data(step)
|
21
|
-
recipe.dig('steps', step)
|
22
|
-
end
|
23
|
-
|
24
|
-
def step_output(step)
|
25
|
-
recipe.dig('steps', step, 'output')
|
26
|
-
end
|
27
|
-
|
28
|
-
def step_repetitions(step)
|
29
|
-
recipe.dig('steps', step, 'repetitions')
|
30
|
-
end
|
31
|
-
|
32
|
-
def total_steps
|
33
|
-
recipe['steps'].size
|
34
|
-
end
|
35
10
|
end
|
36
11
|
end
|
@@ -10,6 +10,7 @@ module MetaWorkflows
|
|
10
10
|
attribute :current_step, :integer, default: 0
|
11
11
|
attribute :completed, :boolean, default: false
|
12
12
|
attribute :workflow_params, :json, default: -> { {} }
|
13
|
+
attribute :recipe, :json, default: -> { {} }
|
13
14
|
|
14
15
|
validates :current_step, presence: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
15
16
|
validates :completed, inclusion: { in: [true, false] }
|
@@ -17,5 +18,29 @@ module MetaWorkflows
|
|
17
18
|
def increment_step
|
18
19
|
update(current_step: current_step + 1)
|
19
20
|
end
|
21
|
+
|
22
|
+
def step_progress(step)
|
23
|
+
recipe&.dig('steps', step, 'step_progress')
|
24
|
+
end
|
25
|
+
|
26
|
+
def prompt_id(step)
|
27
|
+
recipe&.dig('steps', step, 'prompt_id')
|
28
|
+
end
|
29
|
+
|
30
|
+
def step_data(step)
|
31
|
+
recipe&.dig('steps', step)
|
32
|
+
end
|
33
|
+
|
34
|
+
def step_output(step)
|
35
|
+
recipe&.dig('steps', step, 'output')
|
36
|
+
end
|
37
|
+
|
38
|
+
def step_repetitions(step)
|
39
|
+
recipe&.dig('steps', step, 'repetitions')
|
40
|
+
end
|
41
|
+
|
42
|
+
def total_steps
|
43
|
+
recipe&.dig('steps')&.size || 0
|
44
|
+
end
|
20
45
|
end
|
21
46
|
end
|
@@ -142,12 +142,12 @@
|
|
142
142
|
</td>
|
143
143
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
144
144
|
<% if execution.completed? %>
|
145
|
-
Step <%= execution.
|
145
|
+
Step <%= execution.total_steps %>
|
146
146
|
<% else %>
|
147
147
|
Step <%= execution.current_step + 1 %>
|
148
148
|
<% current_step_obj = execution.workflow_steps.find_by(step: execution.current_step) %>
|
149
|
-
<% max_repetitions = execution.
|
150
|
-
|
149
|
+
<% max_repetitions = execution.step_repetitions(execution.current_step) if current_step_obj %>
|
150
|
+
<% step_data = safe_step_data(execution, execution.current_step) %>
|
151
151
|
|
152
152
|
<% if current_step_obj&.repetition.present? && max_repetitions.present? %>
|
153
153
|
<br><span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-yellow-100 text-yellow-800">
|
@@ -84,7 +84,7 @@
|
|
84
84
|
<div class="flex items-center">
|
85
85
|
<h3 class="text-sm font-medium text-gray-900">
|
86
86
|
Step <%= workflow_step.step + 1 %>
|
87
|
-
<% max_repetitions = @execution.
|
87
|
+
<% max_repetitions = @execution.step_repetitions(workflow_step.step) %>
|
88
88
|
<% if max_repetitions.present? %>
|
89
89
|
<span class="ml-2 inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800">
|
90
90
|
<svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
@@ -105,8 +105,8 @@
|
|
105
105
|
<% end %>
|
106
106
|
</div>
|
107
107
|
|
108
|
-
|
109
|
-
|
108
|
+
<% step_data = safe_step_data(@execution, workflow_step.step) %>
|
109
|
+
<% max_repetitions = @execution.step_repetitions(workflow_step.step) %>
|
110
110
|
|
111
111
|
<% if step_data %>
|
112
112
|
<div class="mt-2 text-sm text-gray-600">
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module MetaWorkflows
|
4
4
|
MAJOR = 0
|
5
5
|
MINOR = 9
|
6
|
-
PATCH =
|
6
|
+
PATCH = 8 # this is automatically incremented by the build process
|
7
7
|
|
8
8
|
VERSION = "#{MetaWorkflows::MAJOR}.#{MetaWorkflows::MINOR}.#{MetaWorkflows::PATCH}".freeze
|
9
9
|
end
|
@@ -21,7 +21,7 @@ module Services
|
|
21
21
|
validate_workflow_presence
|
22
22
|
|
23
23
|
workflow, workflow_execution = find_or_create_workflow_execution
|
24
|
-
execution_step, execution_output, workflow_step = prepare_workflow_execution(
|
24
|
+
execution_step, execution_output, workflow_step = prepare_workflow_execution(workflow_execution)
|
25
25
|
|
26
26
|
if ACTIONS_WITHOUT_CONVERSATION.include?(execution_step['action'])
|
27
27
|
process_action(execution_step, nil, workflow_execution, workflow)
|
@@ -41,11 +41,11 @@ module Services
|
|
41
41
|
when 'human'
|
42
42
|
process_human_action(execution_step, workflow_execution)
|
43
43
|
when 'record_redirect'
|
44
|
-
process_record_redirect_action(workflow_execution
|
44
|
+
process_record_redirect_action(workflow_execution)
|
45
45
|
when 'collection_create'
|
46
|
-
process_collection_create_action(execution_step, workflow_execution
|
46
|
+
process_collection_create_action(execution_step, workflow_execution)
|
47
47
|
when 'record_update'
|
48
|
-
process_record_update_action(execution_step, workflow_execution
|
48
|
+
process_record_update_action(execution_step, workflow_execution)
|
49
49
|
else
|
50
50
|
raise ArgumentError, "The action #{execution_step['action']} does not exist"
|
51
51
|
end
|
@@ -57,7 +57,7 @@ module Services
|
|
57
57
|
begin
|
58
58
|
clear_previous_errors(workflow_step)
|
59
59
|
execute_llm_call(conversation, workflow_execution)
|
60
|
-
handle_workflow_continuation(workflow_execution,
|
60
|
+
handle_workflow_continuation(workflow_execution, conversation)
|
61
61
|
rescue StandardError => e
|
62
62
|
handle_agent_error(e, workflow_step, workflow, workflow_execution)
|
63
63
|
raise
|
@@ -77,10 +77,10 @@ module Services
|
|
77
77
|
workflow_execution.increment_step
|
78
78
|
end
|
79
79
|
|
80
|
-
def handle_workflow_continuation(workflow_execution,
|
80
|
+
def handle_workflow_continuation(workflow_execution, conversation)
|
81
81
|
new_inputs = extract_tool_call_inputs(conversation)
|
82
82
|
|
83
|
-
if workflow_execution.current_step <
|
83
|
+
if workflow_execution.current_step < workflow_execution.total_steps
|
84
84
|
schedule_next_workflow_step_with_inputs(new_inputs)
|
85
85
|
else
|
86
86
|
workflow_execution.update(completed: true)
|
@@ -127,35 +127,35 @@ module Services
|
|
127
127
|
# the step advancement is handled in the human input job
|
128
128
|
end
|
129
129
|
|
130
|
-
def process_record_redirect_action(workflow_execution
|
130
|
+
def process_record_redirect_action(workflow_execution)
|
131
131
|
::MetaWorkflows::RecordRedirectJob.perform_later(workflow_execution: workflow_execution)
|
132
132
|
workflow_execution.increment_step
|
133
133
|
|
134
|
-
return unless workflow_execution.current_step >=
|
134
|
+
return unless workflow_execution.current_step >= workflow_execution.total_steps
|
135
135
|
|
136
136
|
workflow_execution.update(completed: true)
|
137
137
|
end
|
138
138
|
|
139
|
-
def process_collection_create_action(execution_step, workflow_execution
|
139
|
+
def process_collection_create_action(execution_step, workflow_execution)
|
140
140
|
service = build_collection_service(execution_step, workflow_execution)
|
141
141
|
|
142
142
|
begin
|
143
143
|
service.call
|
144
144
|
workflow_execution.increment_step
|
145
|
-
continue_workflow(workflow_execution
|
145
|
+
continue_workflow(workflow_execution)
|
146
146
|
rescue StandardError => e
|
147
147
|
Rails.logger.error("Error creating collection: #{e.message}")
|
148
148
|
# The workflow should halt on error per requirements - do not increment step
|
149
149
|
end
|
150
150
|
end
|
151
151
|
|
152
|
-
def process_record_update_action(execution_step, workflow_execution
|
152
|
+
def process_record_update_action(execution_step, workflow_execution)
|
153
153
|
service = build_record_update_service(execution_step, workflow_execution)
|
154
154
|
|
155
155
|
begin
|
156
156
|
service.call
|
157
157
|
workflow_execution.increment_step
|
158
|
-
continue_workflow(workflow_execution
|
158
|
+
continue_workflow(workflow_execution)
|
159
159
|
rescue StandardError => e
|
160
160
|
Rails.logger.error("Error updating record: #{e.message}")
|
161
161
|
# Let Sidekiq handle retry - reraise the error
|
@@ -192,8 +192,8 @@ module Services
|
|
192
192
|
record_class.find(workflow_execution.record_id)
|
193
193
|
end
|
194
194
|
|
195
|
-
def continue_workflow(workflow_execution
|
196
|
-
if workflow_execution.current_step <
|
195
|
+
def continue_workflow(workflow_execution)
|
196
|
+
if workflow_execution.current_step < workflow_execution.total_steps
|
197
197
|
schedule_next_workflow_step
|
198
198
|
else
|
199
199
|
workflow_execution.update(completed: true)
|
@@ -246,7 +246,8 @@ module Services
|
|
246
246
|
workflow: workflow,
|
247
247
|
current_step: 0,
|
248
248
|
completed: false,
|
249
|
-
workflow_params: workflow_params
|
249
|
+
workflow_params: workflow_params,
|
250
|
+
recipe: workflow.recipe
|
250
251
|
)
|
251
252
|
else
|
252
253
|
workflow_execution = active_workflow_execution
|
@@ -261,9 +262,9 @@ module Services
|
|
261
262
|
record.workflow_executions.order(created_at: :desc).first
|
262
263
|
end
|
263
264
|
|
264
|
-
def prepare_workflow_execution(
|
265
|
-
execution_step =
|
266
|
-
execution_output =
|
265
|
+
def prepare_workflow_execution(workflow_execution)
|
266
|
+
execution_step = workflow_execution.step_data(workflow_execution.current_step)
|
267
|
+
execution_output = workflow_execution.step_output(workflow_execution.current_step)
|
267
268
|
workflow_step = workflow_execution.workflow_steps.find_or_create_by(step: workflow_execution.current_step)
|
268
269
|
|
269
270
|
[execution_step, execution_output, workflow_step]
|
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.8
|
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-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -180,6 +180,7 @@ files:
|
|
180
180
|
- db/migrate/20250617192849_remove_repetition_from_meta_workflows_workflow_executions.rb
|
181
181
|
- db/migrate/20250618175439_add_call_id_and_status_to_meta_workflows_tool_calls.rb
|
182
182
|
- db/migrate/20250626211926_add_repetition_to_meta_workflows_workflow_steps.rb
|
183
|
+
- db/migrate/20250709153017_add_recipe_to_meta_workflows_workflow_executions.rb
|
183
184
|
- lib/meta_workflows.rb
|
184
185
|
- lib/meta_workflows/asset_installer.rb
|
185
186
|
- lib/meta_workflows/configuration.rb
|