completion-kit 0.28.19 → 0.28.20
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/completion_kit/api/v1/runs_controller.rb +2 -30
- data/app/controllers/completion_kit/runs_controller.rb +2 -32
- data/app/models/completion_kit/run.rb +39 -0
- data/app/services/completion_kit/mcp_tools/runs.rb +66 -7
- data/lib/completion_kit/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6a05f4f94c9f7663a486ca16dcf6d7a60215b3c8017be6576760dd929a6df49d
|
|
4
|
+
data.tar.gz: d5e26b475bb73c1402d68856f833d91241a6feac0402fdfd0e1ab605a658578f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b0153fca04674849516b94f8d12021be77dedec325e8e716e40037699194002102ac28fb80ffccc2f01c1cd08a7ddca498055f352ac6bdb5e00721e3c2a39732
|
|
7
|
+
data.tar.gz: 6b11f2fbd4e155b191f27c561624b3e2ba7ee0358ffc2f97e6430749ee251c6a0ad628696d9b1f48c5827ebce91001d583ab7a2d07c796dd2c28b695db16a7aa
|
|
@@ -54,40 +54,12 @@ module CompletionKit
|
|
|
54
54
|
return render_error("Judge has changed since this run executed. Retry would mix versions in the same run; use POST /api/v1/runs/:id/rerun instead.", status: :conflict)
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
scope = scope.where(id: params[:only]) if params[:only].present?
|
|
59
|
-
|
|
60
|
-
ActiveRecord::Base.transaction do
|
|
61
|
-
failed_response_ids = scope.pluck(:id)
|
|
62
|
-
CompletionKit::Review.where(response_id: failed_response_ids, status: "failed").update_all(
|
|
63
|
-
status: "pending", attempts: 0,
|
|
64
|
-
error_provider: nil, error_class: nil, error_status: nil, error_message: nil,
|
|
65
|
-
ai_score: nil, passed: nil, ai_feedback: nil
|
|
66
|
-
)
|
|
67
|
-
scope.update_all(
|
|
68
|
-
status: "pending", attempts: 0,
|
|
69
|
-
error_provider: nil, error_class: nil, error_status: nil, error_message: nil,
|
|
70
|
-
response_text: nil
|
|
71
|
-
)
|
|
72
|
-
@run.update!(status: "running")
|
|
73
|
-
failed_response_ids.each { |rid| CompletionKit::GenerateRowJob.perform_later(@run.id, rid) }
|
|
74
|
-
end
|
|
75
|
-
|
|
57
|
+
@run.retry_failures!(only: params[:only])
|
|
76
58
|
render json: @run.reload, status: :accepted
|
|
77
59
|
end
|
|
78
60
|
|
|
79
61
|
def rerun
|
|
80
|
-
new_run =
|
|
81
|
-
prompt_id: @run.prompt_id,
|
|
82
|
-
dataset_id: @run.dataset_id,
|
|
83
|
-
judge_model: @run.judge_model,
|
|
84
|
-
temperature: @run.temperature,
|
|
85
|
-
output_column: @run.output_column,
|
|
86
|
-
expected_column: @run.expected_column,
|
|
87
|
-
tag_names: @run.tag_names,
|
|
88
|
-
status: "pending"
|
|
89
|
-
)
|
|
90
|
-
new_run.replace_metrics!(@run.metric_ids)
|
|
62
|
+
new_run = @run.rerun!
|
|
91
63
|
if new_run.start!
|
|
92
64
|
render json: new_run.reload, status: :accepted
|
|
93
65
|
else
|
|
@@ -110,17 +110,7 @@ module CompletionKit
|
|
|
110
110
|
end
|
|
111
111
|
|
|
112
112
|
def rerun
|
|
113
|
-
new_run =
|
|
114
|
-
prompt_id: @run.prompt_id,
|
|
115
|
-
dataset_id: @run.dataset_id,
|
|
116
|
-
judge_model: @run.judge_model,
|
|
117
|
-
temperature: @run.temperature,
|
|
118
|
-
output_column: @run.output_column,
|
|
119
|
-
expected_column: @run.expected_column,
|
|
120
|
-
tag_names: @run.tag_names,
|
|
121
|
-
status: "pending"
|
|
122
|
-
)
|
|
123
|
-
new_run.replace_metrics!(@run.metric_ids)
|
|
113
|
+
new_run = @run.rerun!
|
|
124
114
|
if new_run.start!
|
|
125
115
|
redirect_to run_path(new_run), notice: "Re-running with the same configuration."
|
|
126
116
|
else
|
|
@@ -162,27 +152,7 @@ module CompletionKit
|
|
|
162
152
|
return
|
|
163
153
|
end
|
|
164
154
|
|
|
165
|
-
|
|
166
|
-
scope = scope.where(id: params[:only]) if params[:only].present?
|
|
167
|
-
|
|
168
|
-
ActiveRecord::Base.transaction do
|
|
169
|
-
failed_response_ids = scope.pluck(:id)
|
|
170
|
-
Review.where(response_id: failed_response_ids, status: "failed").update_all(
|
|
171
|
-
status: "pending",
|
|
172
|
-
attempts: 0,
|
|
173
|
-
error_provider: nil, error_class: nil, error_status: nil, error_message: nil,
|
|
174
|
-
ai_score: nil, passed: nil, ai_feedback: nil
|
|
175
|
-
)
|
|
176
|
-
scope.update_all(
|
|
177
|
-
status: "pending",
|
|
178
|
-
attempts: 0,
|
|
179
|
-
error_provider: nil, error_class: nil, error_status: nil, error_message: nil,
|
|
180
|
-
response_text: nil
|
|
181
|
-
)
|
|
182
|
-
@run.update!(status: "running")
|
|
183
|
-
failed_response_ids.each { |rid| GenerateRowJob.perform_later(@run.id, rid) }
|
|
184
|
-
end
|
|
185
|
-
|
|
155
|
+
@run.retry_failures!(only: params[:only])
|
|
186
156
|
@run.broadcast_ui
|
|
187
157
|
redirect_to run_path(@run)
|
|
188
158
|
end
|
|
@@ -307,6 +307,45 @@ module CompletionKit
|
|
|
307
307
|
true
|
|
308
308
|
end
|
|
309
309
|
|
|
310
|
+
def rerun!
|
|
311
|
+
new_run = Run.create!(
|
|
312
|
+
prompt_id: prompt_id,
|
|
313
|
+
dataset_id: dataset_id,
|
|
314
|
+
judge_model: judge_model,
|
|
315
|
+
temperature: temperature,
|
|
316
|
+
output_column: output_column,
|
|
317
|
+
expected_column: expected_column,
|
|
318
|
+
tag_names: tag_names,
|
|
319
|
+
status: "pending"
|
|
320
|
+
)
|
|
321
|
+
new_run.replace_metrics!(metric_ids)
|
|
322
|
+
new_run
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
def retry_failures!(only: nil)
|
|
326
|
+
scope = responses.where(status: "failed")
|
|
327
|
+
scope = scope.where(id: only) if only.present?
|
|
328
|
+
|
|
329
|
+
transaction do
|
|
330
|
+
failed_response_ids = scope.pluck(:id)
|
|
331
|
+
Review.where(response_id: failed_response_ids, status: "failed").update_all(
|
|
332
|
+
status: "pending",
|
|
333
|
+
attempts: 0,
|
|
334
|
+
error_provider: nil, error_class: nil, error_status: nil, error_message: nil,
|
|
335
|
+
ai_score: nil, passed: nil, ai_feedback: nil
|
|
336
|
+
)
|
|
337
|
+
scope.update_all(
|
|
338
|
+
status: "pending",
|
|
339
|
+
attempts: 0,
|
|
340
|
+
error_provider: nil, error_class: nil, error_status: nil, error_message: nil,
|
|
341
|
+
response_text: nil
|
|
342
|
+
)
|
|
343
|
+
update!(status: "running")
|
|
344
|
+
failed_response_ids.each { |rid| GenerateRowJob.perform_later(id, rid) }
|
|
345
|
+
end
|
|
346
|
+
self
|
|
347
|
+
end
|
|
348
|
+
|
|
310
349
|
def progress_snapshot
|
|
311
350
|
generated_done = responses.where(status: "succeeded").count
|
|
312
351
|
generated_failed = responses.where(status: "failed").count
|
|
@@ -24,6 +24,7 @@ module CompletionKit
|
|
|
24
24
|
output_column: {type: "string", description: "Dataset column to grade when prompt_id is omitted; defaults to \"actual_output\"."},
|
|
25
25
|
expected_column: {type: "string", description: "Dataset column holding each row's answer key / ground truth, graded by checks with compare_to \"expected\" and passed to the judge; defaults to \"expected_output\"."},
|
|
26
26
|
metric_ids: {type: "array", items: {type: "integer"}},
|
|
27
|
+
metric_group_id: {type: "integer", description: "Attach the metrics belonging to this metric group (its current metric_ids). Ignored when metric_ids is also given."},
|
|
27
28
|
tag_names: {type: "array", items: {type: "string"}}
|
|
28
29
|
},
|
|
29
30
|
required: ["name"]
|
|
@@ -40,6 +41,7 @@ module CompletionKit
|
|
|
40
41
|
output_column: {type: "string"},
|
|
41
42
|
expected_column: {type: "string"},
|
|
42
43
|
metric_ids: {type: "array", items: {type: "integer"}},
|
|
44
|
+
metric_group_id: {type: "integer", description: "Replace the run's metrics with those belonging to this metric group. Ignored when metric_ids is also given."},
|
|
43
45
|
tag_names: {type: "array", items: {type: "string"}}
|
|
44
46
|
},
|
|
45
47
|
required: ["id"]
|
|
@@ -55,6 +57,21 @@ module CompletionKit
|
|
|
55
57
|
description: "Start a run. Required for every run, including score-only runs (no prompt): generates responses with the prompt when there is one, otherwise copies the graded dataset column and grades it.",
|
|
56
58
|
inputSchema: {type: "object", properties: {id: {type: "integer"}}, required: ["id"]},
|
|
57
59
|
handler: :generate
|
|
60
|
+
},
|
|
61
|
+
"runs_regrade" => {
|
|
62
|
+
description: "Re-grade a run's existing responses with its currently attached metrics, without regenerating. Use after attaching or editing metrics on an already-generated run.",
|
|
63
|
+
inputSchema: {type: "object", properties: {id: {type: "integer"}}, required: ["id"]},
|
|
64
|
+
handler: :regrade
|
|
65
|
+
},
|
|
66
|
+
"runs_rerun" => {
|
|
67
|
+
description: "Create and start a fresh copy of a run with the same prompt, dataset, metrics, and settings. Use when the judge changed and you want a clean run instead of mixing versions.",
|
|
68
|
+
inputSchema: {type: "object", properties: {id: {type: "integer"}}, required: ["id"]},
|
|
69
|
+
handler: :rerun
|
|
70
|
+
},
|
|
71
|
+
"runs_retry_failures" => {
|
|
72
|
+
description: "Re-run only the failed responses of a run, optionally limited to specific response ids via \"only\".",
|
|
73
|
+
inputSchema: {type: "object", properties: {id: {type: "integer"}, only: {type: "array", items: {type: "integer"}}}, required: ["id"]},
|
|
74
|
+
handler: :retry_failures
|
|
58
75
|
}
|
|
59
76
|
}.freeze
|
|
60
77
|
|
|
@@ -63,15 +80,15 @@ module CompletionKit
|
|
|
63
80
|
end
|
|
64
81
|
|
|
65
82
|
def self.get(args)
|
|
66
|
-
text_result(Run.find(args["id"])
|
|
83
|
+
text_result(run_payload(Run.find(args["id"])))
|
|
67
84
|
end
|
|
68
85
|
|
|
69
86
|
def self.create(args)
|
|
70
87
|
run = Run.new(args.slice("name", "prompt_id", "dataset_id", "judge_model", "output_column", "expected_column"))
|
|
71
88
|
if run.save
|
|
72
|
-
run.replace_metrics!(args
|
|
89
|
+
run.replace_metrics!(resolve_metric_ids(args))
|
|
73
90
|
run.update!(tag_names: args["tag_names"]) if args.key?("tag_names")
|
|
74
|
-
text_result(run.reload
|
|
91
|
+
text_result(run_payload(run.reload))
|
|
75
92
|
else
|
|
76
93
|
error_result(run.errors.full_messages.join(", "))
|
|
77
94
|
end
|
|
@@ -79,10 +96,10 @@ module CompletionKit
|
|
|
79
96
|
|
|
80
97
|
def self.update(args)
|
|
81
98
|
run = Run.find(args["id"])
|
|
82
|
-
if run.update(args.except("id", "metric_ids", "tag_names").slice("name", "dataset_id", "judge_model", "output_column", "expected_column"))
|
|
83
|
-
run.replace_metrics!(args
|
|
99
|
+
if run.update(args.except("id", "metric_ids", "metric_group_id", "tag_names").slice("name", "dataset_id", "judge_model", "output_column", "expected_column"))
|
|
100
|
+
run.replace_metrics!(resolve_metric_ids(args)) if args.key?("metric_ids") || args["metric_group_id"].present?
|
|
84
101
|
run.update!(tag_names: args["tag_names"]) if args.key?("tag_names")
|
|
85
|
-
text_result(run.reload
|
|
102
|
+
text_result(run_payload(run.reload))
|
|
86
103
|
else
|
|
87
104
|
error_result(run.errors.full_messages.join(", "))
|
|
88
105
|
end
|
|
@@ -96,11 +113,53 @@ module CompletionKit
|
|
|
96
113
|
def self.generate(args)
|
|
97
114
|
run = Run.find(args["id"])
|
|
98
115
|
if run.start!
|
|
99
|
-
text_result(run.reload
|
|
116
|
+
text_result(run_payload(run.reload))
|
|
100
117
|
else
|
|
101
118
|
text_result(run.failure_summary || run.errors.full_messages.to_sentence)
|
|
102
119
|
end
|
|
103
120
|
end
|
|
121
|
+
|
|
122
|
+
def self.regrade(args)
|
|
123
|
+
run = Run.find(args["id"])
|
|
124
|
+
if run.regrade!
|
|
125
|
+
text_result(run_payload(run.reload))
|
|
126
|
+
else
|
|
127
|
+
error_result("Nothing to re-grade. The run has no succeeded responses or no metrics attached.")
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def self.rerun(args)
|
|
132
|
+
new_run = Run.find(args["id"]).rerun!
|
|
133
|
+
if new_run.start!
|
|
134
|
+
text_result(run_payload(new_run.reload))
|
|
135
|
+
else
|
|
136
|
+
error_result(new_run.failure_summary || "Could not start the new run.")
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def self.retry_failures(args)
|
|
141
|
+
run = Run.find(args["id"])
|
|
142
|
+
if run.stale_review_summary.any?
|
|
143
|
+
return error_result("Judge has changed since this run executed. Retry would mix versions in the same run; use runs_rerun instead.")
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
run.retry_failures!(only: args["only"])
|
|
147
|
+
text_result(run_payload(run.reload))
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def self.resolve_metric_ids(args)
|
|
151
|
+
return args["metric_ids"] if args.key?("metric_ids")
|
|
152
|
+
return MetricGroup.find(args["metric_group_id"]).metric_ids if args["metric_group_id"].present?
|
|
153
|
+
|
|
154
|
+
nil
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def self.run_payload(run)
|
|
158
|
+
json = run.as_json
|
|
159
|
+
return json unless run.metric_ids.empty?
|
|
160
|
+
|
|
161
|
+
json.merge("warning" => "No metrics are attached, so this run judges nothing. Attach metric_ids or a metric_group_id before generating.")
|
|
162
|
+
end
|
|
104
163
|
end
|
|
105
164
|
end
|
|
106
165
|
end
|