completion-kit 0.28.24 → 0.28.32

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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/completion_kit/application.css +73 -5
  3. data/app/controllers/completion_kit/api/v1/prompts_controller.rb +1 -0
  4. data/app/controllers/completion_kit/api/v1/responses_controller.rb +6 -3
  5. data/app/controllers/completion_kit/api/v1/runs_controller.rb +1 -1
  6. data/app/controllers/completion_kit/dashboard_controller.rb +12 -1
  7. data/app/controllers/completion_kit/prompts_controller.rb +1 -0
  8. data/app/controllers/completion_kit/runs_controller.rb +16 -9
  9. data/app/jobs/completion_kit/generate_row_job.rb +1 -1
  10. data/app/jobs/completion_kit/judge_review_job.rb +1 -2
  11. data/app/jobs/completion_kit/run_completion_check_job.rb +4 -0
  12. data/app/jobs/completion_kit/start_run_job.rb +29 -0
  13. data/app/models/completion_kit/prompt_serve.rb +41 -0
  14. data/app/models/completion_kit/run.rb +110 -14
  15. data/app/services/completion_kit/dashboard_stats.rb +54 -0
  16. data/app/services/completion_kit/judge_service.rb +4 -1
  17. data/app/services/completion_kit/mcp_tools/base.rb +12 -0
  18. data/app/services/completion_kit/mcp_tools/responses.rb +38 -3
  19. data/app/services/completion_kit/mcp_tools/runs.rb +33 -5
  20. data/app/services/completion_kit/metric_improvement_validator.rb +1 -2
  21. data/app/services/completion_kit/prompt_improvement_validator.rb +2 -3
  22. data/app/services/completion_kit/response_query.rb +94 -0
  23. data/app/views/completion_kit/api_reference/_body.html.erb +5 -3
  24. data/app/views/completion_kit/dashboard/_failing_checks_card.html.erb +36 -7
  25. data/app/views/completion_kit/dashboard/_failures_card.html.erb +6 -5
  26. data/app/views/completion_kit/dashboard/_worst_metric_card.html.erb +1 -1
  27. data/app/views/completion_kit/dashboard/show.html.erb +48 -9
  28. data/app/views/completion_kit/prompts/show.html.erb +13 -0
  29. data/app/views/completion_kit/responses/show.html.erb +1 -1
  30. data/app/views/completion_kit/runs/_form.html.erb +17 -0
  31. data/app/views/completion_kit/runs/_responses_region.html.erb +20 -0
  32. data/app/views/completion_kit/runs/_status_header.html.erb +22 -0
  33. data/app/views/completion_kit/runs/_status_panel.html.erb +18 -0
  34. data/app/views/completion_kit/runs/show.html.erb +30 -30
  35. data/db/migrate/20260728000001_add_max_tokens_to_completion_kit_runs.rb +5 -0
  36. data/db/migrate/20260730000001_add_judge_temperature_to_completion_kit_runs.rb +5 -0
  37. data/db/migrate/20260730000002_create_completion_kit_prompt_serves.rb +17 -0
  38. data/lib/completion_kit/version.rb +1 -1
  39. data/lib/completion_kit.rb +4 -1
  40. metadata +8 -1
@@ -77,6 +77,24 @@
77
77
  </div>
78
78
  <% end %>
79
79
 
80
+ <% if has_llm_metric && CompletionKit.config.judge_agreement_enabled %>
81
+ <% agreement = run.judge_agreement %>
82
+ <div class="ck-run-status__cell">
83
+ <p class="ck-run-status__metric-label">Judge agreement</p>
84
+ <div class="ck-run-status__cell-value <%= agreement ? "ck-run-status__cell-value--split" : "ck-run-status__cell-value--stack" %>">
85
+ <% if agreement %>
86
+ <span class="<%= ck_badge_classes(ck_pass_rate_kind(agreement[:rate])) %> ck-badge--lg"><%= (agreement[:rate] * 100).round %>%</span>
87
+ <span class="ck-run-status__summary-text"><%= pluralize(agreement[:sample_size], "label") %></span>
88
+ <% else %>
89
+ <span class="ck-run-status__cell-unverified">Unverified</span>
90
+ <% if run.calibratable_metric %>
91
+ <%= link_to "Check the judge &rarr;".html_safe, metric_path(run.calibratable_metric, anchor: "agreement"), class: "ck-cal-link" %>
92
+ <% end %>
93
+ <% end %>
94
+ </div>
95
+ </div>
96
+ <% end %>
97
+
80
98
  <% if has_checks %>
81
99
  <div class="ck-run-status__cell">
82
100
  <p class="ck-run-status__metric-label">Checks passed</p>
@@ -25,20 +25,26 @@
25
25
  This run was scored against metric versions that are no longer live.
26
26
  <% stale_summary.values.each_with_index do |s, i| %>
27
27
  <%= ", " if i > 0 %><strong><%= s[:metric_name] %></strong> (scored by <%= s[:scored_labels].join(", ") %>; live is <%= s[:current_label] %>)<% end %>.
28
- Re-run to refresh the scores with the current metrics.
28
+ Re-grade to refresh the scores with the current metrics.
29
29
  </p>
30
30
  </div>
31
31
  <% if @run.status == "completed" %>
32
- <%= button_to "Re-run from scratch",
33
- rerun_run_path(@run), method: :post,
34
- class: ck_button_classes(:light, variant: :outline), form_class: "inline-block",
35
- title: "Create a new run that regenerates responses and grades them with the current metrics.",
36
- data: { turbo_confirm: "Create a new run with fresh responses and the current metrics? The original run stays as a record." } %>
37
- <%= button_to "Re-grade with current metrics",
38
- regrade_run_path(@run), method: :post,
39
- class: ck_button_classes(:dark), form_class: "inline-block",
40
- title: "Re-grade this run's existing responses against the current metrics. Faster and cheaper than re-running.",
41
- data: { turbo_confirm: "Re-grade this run's existing responses against the current metrics?" } %>
32
+ <div class="ck-banner-actions">
33
+ <div class="ck-banner-action">
34
+ <%= button_to "Re-grade with current metrics",
35
+ regrade_run_path(@run), method: :post,
36
+ class: ck_button_classes(:dark), form_class: "inline-block",
37
+ data: { turbo_confirm: "Re-grade this run's existing responses against the current metrics?" } %>
38
+ <p class="ck-banner-action__note">Re-scores the responses you already have. No generation cost.</p>
39
+ </div>
40
+ <div class="ck-banner-action">
41
+ <%= button_to "Re-run from scratch",
42
+ rerun_run_path(@run), method: :post,
43
+ class: ck_button_classes(:light, variant: :outline), form_class: "inline-block",
44
+ data: { turbo_confirm: "Create a new run with fresh responses and the current metrics? The original run stays as a record." } %>
45
+ <p class="ck-banner-action__note">Generates fresh responses first. Costs a full run.</p>
46
+ </div>
47
+ </div>
42
48
  <% end %>
43
49
  </div>
44
50
  <% end %>
@@ -83,6 +89,17 @@
83
89
  <span class="ck-run-config__warn" style="color: var(--ck-dim);" title="The model rejected the temperature parameter, so CompletionKit re-sent the request without it.">ignored by model</span>
84
90
  <% end %>
85
91
  </div>
92
+ <div class="ck-run-config__row">
93
+ <span class="ck-run-config__key">Max tokens</span>
94
+ <span><%= @run.max_tokens || "Provider default" %></span>
95
+ </div>
96
+ <div class="ck-run-config__row">
97
+ <span class="ck-run-config__key">Judge temperature</span>
98
+ <span><%= @run.judge_temperature %></span>
99
+ <% if @run.nondeterministic_judge? %>
100
+ <span class="ck-run-config__warn" style="color: var(--ck-warning);" title="Judging above temperature 0 makes scores irreproducible. The same output can get a different score on a re-judge.">scores not reproducible</span>
101
+ <% end %>
102
+ </div>
86
103
  </div>
87
104
 
88
105
  <% if @run.prompt %>
@@ -109,7 +126,7 @@
109
126
  <div class="ck-prompt-preview__header">
110
127
  <p class="ck-kicker">Output source</p>
111
128
  </div>
112
- <p class="ck-prompt-preview__text">Dataset column <code><%= @run.output_column.presence || "actual_output" %></code> no prompt generated these outputs.</p>
129
+ <p class="ck-prompt-preview__text">Dataset column <code><%= @run.output_column.presence || "actual_output" %></code>. No prompt generated these outputs.</p>
113
130
  </div>
114
131
  <% end %>
115
132
 
@@ -186,24 +203,7 @@
186
203
 
187
204
  <%= render "sort_toolbar", run: @run %>
188
205
 
189
- <p class="ck-kicker" style="margin-top: 1.5rem;<%= ' display:none;' unless @responses.any? %>" id="responses_kicker">Responses</p>
190
- <table class="ck-results-table ck-responses-table"<%= ' hidden'.html_safe unless @responses.any? %> id="responses_table">
191
- <thead>
192
- <tr>
193
- <th scope="col">#</th>
194
- <th scope="col">Response</th>
195
- <th scope="col">Metrics</th>
196
- <th scope="col">Avg score</th>
197
- <th scope="col">Status</th>
198
- <th scope="col"></th>
199
- </tr>
200
- </thead>
201
- <tbody id="run_responses">
202
- <% @responses.each_with_index do |response, idx| %>
203
- <%= render "response_row", run: @run, response: response, index: @responses_offset + idx + 1 %>
204
- <% end %>
205
- </tbody>
206
- </table>
206
+ <%= render "responses_region", run: @run, responses: @responses, responses_offset: @responses_offset %>
207
207
 
208
208
  <% if @responses_total_pages > 1 %>
209
209
  <nav class="ck-pagination" aria-label="Response pages">
@@ -0,0 +1,5 @@
1
+ class AddMaxTokensToCompletionKitRuns < ActiveRecord::Migration[8.1]
2
+ def change
3
+ add_column :completion_kit_runs, :max_tokens, :integer
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddJudgeTemperatureToCompletionKitRuns < ActiveRecord::Migration[8.1]
2
+ def change
3
+ add_column :completion_kit_runs, :judge_temperature, :float, default: 0.0
4
+ end
5
+ end
@@ -0,0 +1,17 @@
1
+ class CreateCompletionKitPromptServes < ActiveRecord::Migration[8.1]
2
+ def change
3
+ create_table :completion_kit_prompt_serves do |t|
4
+ t.integer :prompt_id
5
+ t.string :family_key, null: false
6
+ t.date :served_on, null: false
7
+ t.integer :serve_count, null: false, default: 0
8
+ t.datetime :last_served_at
9
+ t.timestamps
10
+ end
11
+
12
+ add_index :completion_kit_prompt_serves, [:prompt_id, :served_on],
13
+ unique: true, name: "index_ck_prompt_serves_on_prompt_and_day"
14
+ add_index :completion_kit_prompt_serves, [:family_key, :served_on],
15
+ name: "index_ck_prompt_serves_on_family_and_day"
16
+ end
17
+ end
@@ -1,3 +1,3 @@
1
1
  module CompletionKit
2
- VERSION = "0.28.24"
2
+ VERSION = "0.28.32"
3
3
  end
@@ -53,8 +53,11 @@ module CompletionKit
53
53
  yield(config) if block_given?
54
54
  end
55
55
 
56
+ # current_prompt_payload and render_current_prompt both come through here,
57
+ # so this is the one place a library-side fetch is counted. The REST show
58
+ # action records its own, since it can also resolve by numeric id.
56
59
  def current_prompt(identifier)
57
- Prompt.current_for(identifier)
60
+ Prompt.current_for(identifier).tap { |prompt| PromptServe.record!(prompt) }
58
61
  end
59
62
 
60
63
  def current_prompt_payload(identifier)
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.24
4
+ version: 0.28.32
5
5
  platform: ruby
6
6
  authors:
7
7
  - Damien Bastin
@@ -232,6 +232,7 @@ files:
232
232
  - app/jobs/completion_kit/model_discovery_job.rb
233
233
  - app/jobs/completion_kit/prompt_suggestion_job.rb
234
234
  - app/jobs/completion_kit/run_completion_check_job.rb
235
+ - app/jobs/completion_kit/start_run_job.rb
235
236
  - app/mailers/completion_kit/application_mailer.rb
236
237
  - app/models/completion_kit/agreement.rb
237
238
  - app/models/completion_kit/application_record.rb
@@ -244,6 +245,7 @@ files:
244
245
  - app/models/completion_kit/metric_version.rb
245
246
  - app/models/completion_kit/model.rb
246
247
  - app/models/completion_kit/prompt.rb
248
+ - app/models/completion_kit/prompt_serve.rb
247
249
  - app/models/completion_kit/provider_credential.rb
248
250
  - app/models/completion_kit/response.rb
249
251
  - app/models/completion_kit/review.rb
@@ -303,6 +305,7 @@ files:
303
305
  - app/services/completion_kit/prompt_improvement_validator.rb
304
306
  - app/services/completion_kit/promptfoo_importer.rb
305
307
  - app/services/completion_kit/provider_endpoint.rb
308
+ - app/services/completion_kit/response_query.rb
306
309
  - app/services/completion_kit/run_comparison.rb
307
310
  - app/services/completion_kit/starter_metrics.rb
308
311
  - app/services/completion_kit/worker_health.rb
@@ -368,6 +371,7 @@ files:
368
371
  - app/views/completion_kit/runs/_compare_score.html.erb
369
372
  - app/views/completion_kit/runs/_form.html.erb
370
373
  - app/views/completion_kit/runs/_response_row.html.erb
374
+ - app/views/completion_kit/runs/_responses_region.html.erb
371
375
  - app/views/completion_kit/runs/_row.html.erb
372
376
  - app/views/completion_kit/runs/_sort_toolbar.html.erb
373
377
  - app/views/completion_kit/runs/_status_header.html.erb
@@ -440,6 +444,9 @@ files:
440
444
  - db/migrate/20260708000001_add_api_version_to_completion_kit_provider_credentials.rb
441
445
  - db/migrate/20260713000001_add_catalog_model_count_to_completion_kit_provider_credentials.rb
442
446
  - db/migrate/20260715000001_dedupe_and_unique_index_metric_versions.rb
447
+ - db/migrate/20260728000001_add_max_tokens_to_completion_kit_runs.rb
448
+ - db/migrate/20260730000001_add_judge_temperature_to_completion_kit_runs.rb
449
+ - db/migrate/20260730000002_create_completion_kit_prompt_serves.rb
443
450
  - lib/completion-kit.rb
444
451
  - lib/completion_kit.rb
445
452
  - lib/completion_kit/concurrency_check.rb