completion-kit 0.28.20 → 0.28.21

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6a05f4f94c9f7663a486ca16dcf6d7a60215b3c8017be6576760dd929a6df49d
4
- data.tar.gz: d5e26b475bb73c1402d68856f833d91241a6feac0402fdfd0e1ab605a658578f
3
+ metadata.gz: 8242f60832e3c23d204132839a832e082eb5115c26afd46eb2082ca4e342f908
4
+ data.tar.gz: 5798c4e0f853e3aa5a2ae20291a7909cc5f70dd7baaa5e9bd2765cb5cbbe5f4f
5
5
  SHA512:
6
- metadata.gz: b0153fca04674849516b94f8d12021be77dedec325e8e716e40037699194002102ac28fb80ffccc2f01c1cd08a7ddca498055f352ac6bdb5e00721e3c2a39732
7
- data.tar.gz: 6b11f2fbd4e155b191f27c561624b3e2ba7ee0358ffc2f97e6430749ee251c6a0ad628696d9b1f48c5827ebce91001d583ab7a2d07c796dd2c28b695db16a7aa
6
+ metadata.gz: ec13a779260638ccd8968c9c3be4bd250780fdda06f01ea13b9963553756329cb0c092603a7ee66118e854227bcdb68b2b360e66a1e7830c2cfeffc879bf35d3
7
+ data.tar.gz: 92dd2c71fd38a9cc31638c77927a21a9a53f6ba8a4f4b81dc876f652dbf91c3d601722b402dd71f108d7530ab96442d1d2c113aadf60684ab767902c1e3ec1c9
@@ -6,8 +6,9 @@ module CompletionKit
6
6
  before_action :load_form_collections, only: [:new, :edit, :create, :update]
7
7
 
8
8
  def index
9
- scope = Run.includes(:prompt, :dataset, :tags, responses: :reviews).order(created_at: :desc).display_scoped
10
- @runs = apply_tag_filter(scope)
9
+ scope = Run.includes(:prompt, :dataset, :tags).order(created_at: :desc).display_scoped
10
+ @runs = apply_tag_filter(scope).load
11
+ Run.preload_summaries(@runs)
11
12
  end
12
13
 
13
14
  RESPONSES_PER_PAGE = 100
@@ -14,6 +14,8 @@ module CompletionKit
14
14
  has_many :suggestions, dependent: :destroy
15
15
  has_many :dashboard_dismissals, as: :dismissable, dependent: :destroy
16
16
 
17
+ attr_writer :avg_score, :check_pass_rate, :metric_averages, :response_count
18
+
17
19
  validates :name, presence: true
18
20
  validates :status, inclusion: { in: STATUSES }
19
21
  validate :dataset_supplies_prompt_variables
@@ -34,6 +36,58 @@ module CompletionKit
34
36
  display_scoped.select(:id)
35
37
  end
36
38
 
39
+ # Batch-compute the list-view summaries (response count, avg score, check
40
+ # pass rate, per-metric averages) for a set of runs in a constant number of
41
+ # grouped queries, injecting the results so the index never loads a single
42
+ # response or review object. Mirrors the per-run reader methods exactly.
43
+ def self.preload_summaries(runs)
44
+ runs = runs.to_a
45
+ return runs if runs.empty?
46
+
47
+ run_ids = runs.map(&:id)
48
+ counts = Response.where(run_id: run_ids).group(:run_id).count
49
+
50
+ run_col = Arel.sql("completion_kit_responses.run_id")
51
+ base = Review.joins(:response).where(completion_kit_responses: {run_id: run_ids})
52
+
53
+ run_rows = base.group(run_col).pluck(
54
+ run_col,
55
+ Arel.sql("AVG(ai_score)"),
56
+ Arel.sql("COUNT(passed)"),
57
+ Arel.sql("SUM(CASE WHEN passed THEN 1 ELSE 0 END)")
58
+ )
59
+ run_stats = run_rows.each_with_object({}) do |(rid, avg, resolved, passed), h|
60
+ h[rid] = {avg: avg, resolved: resolved.to_i, passed: passed.to_i}
61
+ end
62
+
63
+ metric_rows = base.group(run_col, :metric_name).pluck(
64
+ run_col,
65
+ :metric_name,
66
+ Arel.sql("AVG(ai_score)"),
67
+ Arel.sql("COUNT(ai_score)"),
68
+ Arel.sql("COUNT(passed)"),
69
+ Arel.sql("SUM(CASE WHEN passed THEN 1 ELSE 0 END)")
70
+ )
71
+ metrics_by_run = metric_rows.group_by(&:first)
72
+
73
+ runs.each do |run|
74
+ run.response_count = counts.fetch(run.id, 0)
75
+
76
+ stats = run_stats[run.id]
77
+ run.avg_score = stats && stats[:avg] ? stats[:avg].to_f.round(2) : nil
78
+ run.check_pass_rate = stats && stats[:resolved] > 0 ? (stats[:passed].to_f / stats[:resolved]).round(2) : nil
79
+
80
+ run.metric_averages = (metrics_by_run[run.id] || []).filter_map do |(_rid, name, avg, scored, resolved, passed)|
81
+ if scored.to_i > 0
82
+ {name: name, avg: avg.to_f.round(1)}
83
+ elsif resolved.to_i > 0
84
+ {name: name, kind: "check", pass_rate: (passed.to_i.to_f / resolved.to_i).round(2)}
85
+ end
86
+ end
87
+ end
88
+ runs
89
+ end
90
+
37
91
  # A scoring-only run grades a pre-existing column on the dataset instead of
38
92
  # generating new outputs. No prompt is attached; the response text is read
39
93
  # from row[output_column]; no LLM generation happens.
@@ -126,7 +180,15 @@ module CompletionKit
126
180
  end
127
181
  end
128
182
 
183
+ def response_count
184
+ return @response_count if defined?(@response_count)
185
+
186
+ responses.size
187
+ end
188
+
129
189
  def avg_score
190
+ return @avg_score if defined?(@avg_score)
191
+
130
192
  scores = reviews_for_summary.map(&:ai_score).compact.map(&:to_f)
131
193
  return nil if scores.empty?
132
194
 
@@ -134,6 +196,8 @@ module CompletionKit
134
196
  end
135
197
 
136
198
  def metric_averages
199
+ return @metric_averages if defined?(@metric_averages)
200
+
137
201
  reviews_for_summary.group_by(&:metric_name).filter_map do |name, reviews|
138
202
  scored = reviews.select { |r| r.ai_score.present? }
139
203
  if scored.any?
@@ -150,6 +214,8 @@ module CompletionKit
150
214
  end
151
215
 
152
216
  def check_pass_rate
217
+ return @check_pass_rate if defined?(@check_pass_rate)
218
+
153
219
  resolved = reviews_for_summary.reject { |r| r.passed.nil? }
154
220
  return nil if resolved.empty?
155
221
 
@@ -27,7 +27,7 @@
27
27
  </td>
28
28
  <td>
29
29
  <span class="ck-runs-table__count">
30
- <%= run.responses.size %><% if run.dataset %><span class="ck-runs-table__count-of">/<%= run.dataset.row_count %></span><% end %>
30
+ <%= run.response_count %><% if run.dataset %><span class="ck-runs-table__count-of">/<%= run.dataset.row_count %></span><% end %>
31
31
  </span>
32
32
  </td>
33
33
  <td>
@@ -1,3 +1,3 @@
1
1
  module CompletionKit
2
- VERSION = "0.28.20"
2
+ VERSION = "0.28.21"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: completion-kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.28.20
4
+ version: 0.28.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - Damien Bastin