completion-kit 0.28.34 → 0.28.36

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: b098378de17e0d51976041f5376929f0fd220bc23e86f1044bf89133b3b7210e
4
- data.tar.gz: 65742e5a42a70e82fe3f4216652e8a80e4b08552eb54cc4a7e8621969a8dd26f
3
+ metadata.gz: 9c91a74066fe93a6df18e5e02a8fc8277bb93f4f15f3d4aed392ab911e88febc
4
+ data.tar.gz: 4d193ac02c79e75763aa97fcc528ab21521ce2ddbf290350818c539746601633
5
5
  SHA512:
6
- metadata.gz: 3ac30e089d1ec6597556b0f4744315d07f1bf94207e174055a6e7ae51ee09f88b180a681ee79cd671cf1887cfee7cd1e99584adda5e95411d8a09ad4c96d5071
7
- data.tar.gz: ba7069754a2f1048da264f66a29e630f220225be24a7078bc4bc6b5a5004d328b02e42046b6b58c5a53a294d293fd386b81eccfbbd7f3b7cfd59d5b545062741
6
+ metadata.gz: 8cbeba6b6a76455b23c4c9f45c88e77c73995e1dfa29bbc4be3acce814633977cd4a00af594df92f77e4740640907cdff520373582d19688aa2aec897bcf84b5
7
+ data.tar.gz: bd564daac0efe50d01a1b0850af2ca452f427ab6496b22a1af88865f4dc01917bb32f50d9b2371be88dbfe56e75acff0adfcd0e5b42f34c32d1ffd3b5f035f81
@@ -130,6 +130,7 @@ module CompletionKit
130
130
  format.turbo_stream do
131
131
  render turbo_stream: [
132
132
  turbo_stream.replace("run_status_header", partial: "completion_kit/runs/status_header", locals: { run: @run }),
133
+ turbo_stream.replace("run_config", partial: "completion_kit/runs/run_config", locals: { run: @run }),
133
134
  turbo_stream.replace("run_status_panel", partial: "completion_kit/runs/status_panel", locals: { run: @run }),
134
135
  turbo_stream.replace("run_responses_region", partial: "completion_kit/runs/responses_region",
135
136
  locals: { run: @run, responses: @responses, responses_offset: @responses_offset })
@@ -222,7 +223,10 @@ module CompletionKit
222
223
  end
223
224
 
224
225
  def run_params
225
- params.require(:run).permit(:name, :prompt_id, :dataset_id, :judge_model, :temperature, :max_tokens, :judge_temperature, :output_column, :expected_column, metric_ids: [], tag_names: [])
226
+ permitted = params.require(:run).permit(:name, :prompt_id, :dataset_id, :judge_model, :temperature, :max_tokens, :judge_temperature, :output_column, :expected_column, :omit_temperature, metric_ids: [], tag_names: [])
227
+ omit = permitted.delete(:omit_temperature)
228
+ permitted[:temperature] = nil if omit == "1"
229
+ permitted
226
230
  end
227
231
 
228
232
  # Editing a run that already has results forks a new run — but only when a
@@ -75,6 +75,10 @@ module CompletionKit
75
75
  record_terminal_failure!(e)
76
76
  enqueue_completion_check
77
77
  return
78
+ ensure
79
+ if judge.temperature_dropped? && !run.judge_temperature_ignored?
80
+ run.update_columns(judge_temperature_ignored: true)
81
+ end
78
82
  end
79
83
 
80
84
  review = response.reviews.find_or_initialize_by(metric_id: metric.id)
@@ -337,7 +337,9 @@ module CompletionKit
337
337
  progress_current: 0,
338
338
  progress_total: 0,
339
339
  failure_summary: nil,
340
- error_message: nil
340
+ error_message: nil,
341
+ temperature_ignored: false,
342
+ judge_temperature_ignored: false
341
343
  )
342
344
  end
343
345
  rescue ActiveRecord::RecordInvalid => e
@@ -436,7 +438,7 @@ module CompletionKit
436
438
  error_status: nil,
437
439
  error_message: nil
438
440
  )
439
- update!(status: "running", failure_summary: nil, error_message: nil)
441
+ update!(status: "running", failure_summary: nil, error_message: nil, judge_temperature_ignored: false)
440
442
 
441
443
  response_ids.each do |rid|
442
444
  llm_metrics.each { |m| JudgeReviewJob.perform_later(rid, m.id, id) } if llm_judge_configured?
@@ -467,7 +469,7 @@ module CompletionKit
467
469
  end
468
470
 
469
471
  def nondeterministic_judge?
470
- judge_temperature.to_f > 0
472
+ judge_temperature.to_f > 0 || judge_temperature_ignored?
471
473
  end
472
474
 
473
475
  def rerun!
@@ -559,6 +561,7 @@ module CompletionKit
559
561
  expected_column: expected_column,
560
562
  created_at: created_at, updated_at: updated_at,
561
563
  max_tokens: max_tokens, judge_temperature: judge_temperature,
564
+ temperature_ignored: temperature_ignored, judge_temperature_ignored: judge_temperature_ignored,
562
565
  responses_count: responses.count, avg_score: avg_score,
563
566
  check_pass_rate: check_pass_rate,
564
567
  metric_averages: metric_averages,
@@ -5,9 +5,6 @@ module CompletionKit
5
5
  { id: "claude-3-5-haiku-latest", name: "Claude 3.5 Haiku" }
6
6
  ].freeze
7
7
 
8
- def temperature_dropped?
9
- @temperature_dropped == true
10
- end
11
8
 
12
9
  def generate_completion(prompt, options = {})
13
10
  @temperature_dropped = false
@@ -15,11 +12,11 @@ module CompletionKit
15
12
 
16
13
  model = options[:model] || "claude-3-7-sonnet-latest"
17
14
  max_tokens = options[:max_tokens] || 1000
18
- temperature = options[:temperature] || 0.7
15
+ temperature = resolve_temperature(options)
19
16
 
20
17
  response = post_messages(model: model, prompt: prompt, max_tokens: max_tokens, temperature: temperature)
21
18
 
22
- if response.status == 400 && temperature_unsupported?(response.body)
19
+ if response.status == 400 && !temperature.nil? && temperature_unsupported?(response.body)
23
20
  @temperature_dropped = true
24
21
  response = post_messages(model: model, prompt: prompt, max_tokens: max_tokens, temperature: nil)
25
22
  end
@@ -97,9 +94,5 @@ module CompletionKit
97
94
  end
98
95
  end
99
96
 
100
- def temperature_unsupported?(body)
101
- s = body.to_s
102
- s.include?("temperature") && (s.include?("deprecated") || s.include?("not supported"))
103
- end
104
97
  end
105
98
  end
@@ -1,8 +1,5 @@
1
1
  module CompletionKit
2
2
  class AzureFoundryClient < LlmClient
3
- def temperature_dropped?
4
- @temperature_dropped == true
5
- end
6
3
 
7
4
  def generate_completion(prompt, options = {})
8
5
  @temperature_dropped = false
@@ -11,7 +8,7 @@ module CompletionKit
11
8
 
12
9
  model = options[:model]
13
10
  max_tokens = options[:max_tokens] || 1000
14
- temperature = options[:temperature] || 0.7
11
+ temperature = resolve_temperature(options)
15
12
  max_completion = false
16
13
 
17
14
  response = post_chat(model: model, prompt: prompt, max_tokens: max_tokens, temperature: temperature, max_completion: max_completion)
@@ -129,10 +126,6 @@ module CompletionKit
129
126
  end
130
127
  end
131
128
 
132
- def temperature_unsupported?(body)
133
- s = body.to_s
134
- s.include?("temperature") && (s.include?("deprecated") || s.include?("not supported") || s.include?("Unsupported parameter"))
135
- end
136
129
 
137
130
  def max_tokens_unsupported?(body)
138
131
  s = body.to_s
@@ -13,6 +13,10 @@ module CompletionKit
13
13
  @judge_client = LlmClient.for_model(@judge_model, ApiConfig.for_model(@judge_model))
14
14
  end
15
15
 
16
+ def temperature_dropped?
17
+ @judge_client.temperature_dropped?
18
+ end
19
+
16
20
  def evaluate(output, expected_output = nil, prompt = nil, criteria: nil, rubric_text: nil, input_data: nil, human_examples: nil, **_extras)
17
21
  raise CompletionKit::ConfigurationError, "Judge not configured" unless @judge_client.configured?
18
22
 
@@ -4,10 +4,46 @@ require "json"
4
4
 
5
5
  module CompletionKit
6
6
  class LlmClient
7
+ DEFAULT_TEMPERATURE = 0.7
8
+
9
+ # Providers phrase a temperature refusal every which way. OpenAI's current
10
+ # reasoning models say "Unsupported value: 'temperature' does not support
11
+ # 0.7 with this model. Only the default (1) value is supported.", which
12
+ # shares no wording with Azure's "Unsupported parameter" or Anthropic's
13
+ # "not supported". Matching on any one phrasing silently turns a
14
+ # recoverable refusal into a failed row.
15
+ #
16
+ # The wording can sit on either side of the parameter name, so both orders
17
+ # carry the same phrase set, and a provider that names the offending field
18
+ # outright gets a branch of its own.
19
+ #
20
+ # Neither gap may cross a brace, which stops a refusal aimed at some other
21
+ # parameter from matching a temperature echoed back in a neighbouring
22
+ # object of the same body. The phrase-first gap additionally bars commas,
23
+ # because "unsupported parameter: logprobs. Supported: model, prompt,
24
+ # temperature" is a list of what IS allowed and must not read as a refusal.
25
+ # The temperature-first gap has to allow commas, since "temperature, top_p
26
+ # and top_k are not supported" is a genuine refusal.
27
+ REFUSAL_PHRASE = /
28
+ deprecated | not\s+supported | does\s+not\s+support |
29
+ only\s+the\s+default | unsupported\s+(?:parameter|value)
30
+ /xi
31
+ TEMPERATURE_REFUSAL = /
32
+ temperature [^{}]{0,80}? #{REFUSAL_PHRASE}
33
+ |
34
+ #{REFUSAL_PHRASE} [^{},]{0,80}? temperature
35
+ |
36
+ "param" \s*:\s* "temperature"
37
+ /xi
38
+
7
39
  def initialize(config = {})
8
40
  @config = config
9
41
  end
10
42
 
43
+ def temperature_dropped?
44
+ @temperature_dropped == true
45
+ end
46
+
11
47
  def generate_completion(prompt, options = {})
12
48
  raise NotImplementedError, "Subclasses must implement generate_completion"
13
49
  end
@@ -50,6 +86,17 @@ module CompletionKit
50
86
 
51
87
  protected
52
88
 
89
+ # An explicit nil means the caller wants no temperature sent at all, which
90
+ # is the only request many current models accept. An absent key still gets
91
+ # the historical default.
92
+ def resolve_temperature(options)
93
+ options.key?(:temperature) ? options[:temperature] : DEFAULT_TEMPERATURE
94
+ end
95
+
96
+ def temperature_unsupported?(body)
97
+ TEMPERATURE_REFUSAL.match?(body.to_s)
98
+ end
99
+
53
100
  def build_connection(url, timeout: nil, open_timeout: nil)
54
101
  Faraday.new(url: url) do |f|
55
102
  f.options.timeout = timeout if timeout
@@ -4,7 +4,9 @@ module CompletionKit
4
4
  extend Base
5
5
 
6
6
  TEMPERATURE_DESCRIPTION = "Sampling temperature for generation, 0 to 1. Defaults to the column default. " \
7
- "Reasoning models ignore it and the run is flagged temperature_ignored.".freeze
7
+ "Reasoning models ignore it and the run is flagged temperature_ignored. " \
8
+ "Pass null to send no temperature at all, which is what models that refuse " \
9
+ "the parameter require.".freeze
8
10
 
9
11
  MAX_TOKENS_DESCRIPTION = "Cap on generated tokens per row. Leave unset to use the provider client's default, " \
10
12
  "which is what silently truncates long outputs and makes the judge score malformed " \
@@ -181,7 +183,9 @@ module CompletionKit
181
183
  if run.metric_ids.empty?
182
184
  warnings << "No metrics are attached, so this run judges nothing. Attach metric_ids or a metric_group_id before generating."
183
185
  end
184
- if run.nondeterministic_judge?
186
+ if run.judge_temperature_ignored?
187
+ warnings << "The judge model refused the temperature parameter, so it was re-sent without one and the provider applied its own default. judge_temperature reads #{run.judge_temperature} but was never applied, and these scores are not reproducible. Pick a judge model that accepts temperature if you need reproducible scoring."
188
+ elsif run.nondeterministic_judge?
185
189
  warnings << "Judge temperature is #{run.judge_temperature}. Judging above 0 makes scores irreproducible: the same output can get a different score on a re-judge. Set judge_temperature to 0 unless you are deliberately measuring judge variance."
186
190
  end
187
191
  return json if warnings.empty?
@@ -1,8 +1,5 @@
1
1
  module CompletionKit
2
2
  class OllamaClient < LlmClient
3
- def temperature_dropped?
4
- @temperature_dropped == true
5
- end
6
3
 
7
4
  def generate_completion(prompt, options = {})
8
5
  @temperature_dropped = false
@@ -11,11 +8,11 @@ module CompletionKit
11
8
 
12
9
  model = options[:model]
13
10
  max_tokens = options[:max_tokens] || 1000
14
- temperature = options[:temperature] || 0.7
11
+ temperature = resolve_temperature(options)
15
12
 
16
13
  response = post_completion(model: model, prompt: prompt, max_tokens: max_tokens, temperature: temperature)
17
14
 
18
- if response.status == 400 && temperature_unsupported?(response.body)
15
+ if response.status == 400 && !temperature.nil? && temperature_unsupported?(response.body)
19
16
  @temperature_dropped = true
20
17
  response = post_completion(model: model, prompt: prompt, max_tokens: max_tokens, temperature: nil)
21
18
  end
@@ -97,9 +94,5 @@ module CompletionKit
97
94
  end
98
95
  end
99
96
 
100
- def temperature_unsupported?(body)
101
- s = body.to_s
102
- s.include?("temperature") && (s.include?("deprecated") || s.include?("not supported") || s.include?("Unsupported parameter"))
103
- end
104
97
  end
105
98
  end
@@ -6,9 +6,6 @@ module CompletionKit
6
6
  { id: "gpt-4o-mini", name: "GPT-4o Mini" }
7
7
  ].freeze
8
8
 
9
- def temperature_dropped?
10
- @temperature_dropped == true
11
- end
12
9
 
13
10
  def generate_completion(prompt, options = {})
14
11
  @temperature_dropped = false
@@ -16,11 +13,11 @@ module CompletionKit
16
13
 
17
14
  model = options[:model] || "gpt-4.1-mini"
18
15
  max_tokens = options[:max_tokens] || 8192
19
- temperature = options[:temperature] || 0.7
16
+ temperature = resolve_temperature(options)
20
17
 
21
18
  response = post_responses(model: model, prompt: prompt, max_tokens: max_tokens, temperature: temperature)
22
19
 
23
- if response.status == 400 && temperature_unsupported?(response.body)
20
+ if response.status == 400 && !temperature.nil? && temperature_unsupported?(response.body)
24
21
  @temperature_dropped = true
25
22
  response = post_responses(model: model, prompt: prompt, max_tokens: max_tokens, temperature: nil)
26
23
  end
@@ -38,7 +35,7 @@ module CompletionKit
38
35
  data = JSON.parse(response.body)
39
36
  if data["status"] == "incomplete"
40
37
  reason = data.dig("incomplete_details", "reason") || "unknown"
41
- return "Error: response incomplete (#{reason}) increase max_tokens=#{max_tokens} or pick a non-reasoning judge model"
38
+ return "Error: response incomplete (#{reason}). Increase max_tokens=#{max_tokens} or pick a non-reasoning judge model"
42
39
  end
43
40
  message = Array(data["output"]).find { |o| o["type"] == "message" }
44
41
  content = message&.dig("content", 0, "text").to_s.strip
@@ -93,9 +90,5 @@ module CompletionKit
93
90
  end
94
91
  end
95
92
 
96
- def temperature_unsupported?(body)
97
- s = body.to_s
98
- s.include?("temperature") && (s.include?("deprecated") || s.include?("not supported") || s.include?("Unsupported parameter"))
99
- end
100
93
  end
101
94
  end
@@ -4,9 +4,6 @@ module CompletionKit
4
4
  REFERER = "https://completionkit.com".freeze
5
5
  APP_TITLE = "CompletionKit".freeze
6
6
 
7
- def temperature_dropped?
8
- @temperature_dropped == true
9
- end
10
7
 
11
8
  def generate_completion(prompt, options = {})
12
9
  @temperature_dropped = false
@@ -14,11 +11,11 @@ module CompletionKit
14
11
 
15
12
  model = options[:model] || "openai/gpt-4o-mini"
16
13
  max_tokens = options[:max_tokens] || 8192
17
- temperature = options[:temperature] || 0.7
14
+ temperature = resolve_temperature(options)
18
15
 
19
16
  response = post_chat(model: model, prompt: prompt, max_tokens: max_tokens, temperature: temperature)
20
17
 
21
- if response.status == 400 && temperature_unsupported?(response.body)
18
+ if response.status == 400 && !temperature.nil? && temperature_unsupported?(response.body)
22
19
  @temperature_dropped = true
23
20
  response = post_chat(model: model, prompt: prompt, max_tokens: max_tokens, temperature: nil)
24
21
  end
@@ -90,9 +87,5 @@ module CompletionKit
90
87
  end
91
88
  end
92
89
 
93
- def temperature_unsupported?(body)
94
- s = body.to_s
95
- s.include?("temperature") && (s.include?("deprecated") || s.include?("not supported") || s.include?("Unsupported parameter"))
96
- end
97
90
  end
98
91
  end
@@ -85,12 +85,21 @@
85
85
 
86
86
  <div class="ck-field">
87
87
  <label class="ck-label" for="run_temperature" style="position: relative;">
88
- Temperature<span class="ck-info-toggle" tabindex="0">?</span><span class="ck-info-popup">Controls how random the model's output is. Lower values are more focused and deterministic the model picks the most likely words. Higher values are more varied and creative, with more risk of odd phrasing. Most LLMs default to 1.0; for evaluation, try a few values and see how your prompt holds up. Newer reasoning models (Claude Opus 4.7, GPT-5 family, etc.) ignore temperature entirely CompletionKit detects this and re-sends without the parameter.</span>
88
+ Temperature<span class="ck-info-toggle" tabindex="0">?</span><span class="ck-info-popup">Controls how random the model's output is. Lower values are more focused and deterministic, so the model picks the most likely words. Higher values are more varied and creative, with more risk of odd phrasing. Most LLMs default to 1.0; for evaluation, try a few values and see how your prompt holds up. Newer reasoning models (Claude Opus 4.7, GPT-5 family, etc.) refuse temperature outright. CompletionKit detects that and re-sends without the parameter, and flags the run so you know the value was never applied. Tick the box below to skip sending it in the first place.</span>
89
89
  </label>
90
90
  <div class="ck-slider-row">
91
- <%= form.range_field :temperature, min: 0, max: 1, step: 0.1, class: "ck-slider", id: "run_temperature", oninput: "document.getElementById('temp-value').textContent = this.value" %>
92
- <span class="ck-slider-value" id="temp-value"><%= run.temperature || 1.0 %></span>
91
+ <%= form.range_field :temperature, min: 0, max: 1, step: 0.1, class: "ck-slider", id: "run_temperature", disabled: run.temperature.nil?, oninput: "document.getElementById('temp-value').textContent = this.value" %>
92
+ <span class="ck-slider-value" id="temp-value"><%= run.temperature.nil? ? "off" : run.temperature %></span>
93
93
  </div>
94
+ <label class="ck-checkbox-label">
95
+ <%= check_box_tag "run[omit_temperature]", "1", run.temperature.nil?, id: "run_omit_temperature", class: "ck-checkbox",
96
+ onchange: "document.getElementById('run_temperature').disabled = this.checked; document.getElementById('temp-value').textContent = this.checked ? 'off' : document.getElementById('run_temperature').value;" %>
97
+ <span class="ck-checkbox-label__box" aria-hidden="true"></span>
98
+ <span class="ck-checkbox-label__body">
99
+ <span class="ck-checkbox-label__text">Send no temperature</span>
100
+ <span class="ck-checkbox-label__hint">The model applies its own default. Required by models that refuse the parameter, which most current frontier models do.</span>
101
+ </span>
102
+ </label>
94
103
  </div>
95
104
 
96
105
  <div class="ck-field">
@@ -0,0 +1,53 @@
1
+ <div class="ck-run-config" id="run_config">
2
+ <div class="ck-run-config__row">
3
+ <span class="ck-run-config__key">Created</span>
4
+ <time datetime="<%= run.created_at.iso8601 %>" data-local-time><%= run.created_at.utc.strftime("%Y-%m-%d %H:%M UTC") %></time>
5
+ </div>
6
+ <div class="ck-run-config__row">
7
+ <span class="ck-run-config__key">Dataset</span>
8
+ <% if run.dataset %>
9
+ <span class="ck-run-config__dataset">
10
+ <%= link_to run.dataset.name, dataset_path(run.dataset), class: "ck-link" %>
11
+ <span class="ck-run-config__dataset-meta"><%= run.dataset.row_count %> rows</span>
12
+ <button type="button" class="ck-run-config__dataset-preview" onclick="document.getElementById('dataset-preview-<%= run.id %>').showModal()">Preview</button>
13
+ </span>
14
+ <% else %>
15
+ <span class="ck-run-config__none">None</span>
16
+ <% end %>
17
+ </div>
18
+ <% if run.judge_model.present? %>
19
+ <div class="ck-run-config__row">
20
+ <span class="ck-run-config__key">Judge</span>
21
+ <span style="text-transform: none;"><%= run.judge_model %></span>
22
+ <% unless run.judge_configured? %>
23
+ <span class="ck-run-config__warn">provider not configured</span>
24
+ <% end %>
25
+ </div>
26
+ <% end %>
27
+ <% if run.metrics.any? %>
28
+ <div class="ck-run-config__row">
29
+ <span class="ck-run-config__key">Metrics</span>
30
+ <span><%= run.metrics.map { |m| link_to(m.name, metric_path(m), class: "ck-link") }.join(", ").html_safe %></span>
31
+ </div>
32
+ <% end %>
33
+ <div class="ck-run-config__row">
34
+ <span class="ck-run-config__key">Temperature</span>
35
+ <span><%= run.temperature.nil? ? "Not sent, provider default" : run.temperature %></span>
36
+ <% if run.temperature_ignored? %>
37
+ <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>
38
+ <% end %>
39
+ </div>
40
+ <div class="ck-run-config__row">
41
+ <span class="ck-run-config__key">Max tokens</span>
42
+ <span><%= run.max_tokens || "Provider default" %></span>
43
+ </div>
44
+ <div class="ck-run-config__row">
45
+ <span class="ck-run-config__key">Judge temperature</span>
46
+ <span><%= run.judge_temperature %></span>
47
+ <% if run.judge_temperature_ignored? %>
48
+ <span class="ck-run-config__warn" style="color: var(--ck-warning);" title="The judge model refused the temperature parameter, so CompletionKit re-sent the request without it and the provider applied its own default. The scores are not reproducible despite the setting above.">refused by judge, not reproducible</span>
49
+ <% elsif run.nondeterministic_judge? %>
50
+ <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>
51
+ <% end %>
52
+ </div>
53
+ </div>
@@ -50,57 +50,7 @@
50
50
  <% end %>
51
51
  <% end %>
52
52
 
53
- <div class="ck-run-config">
54
- <div class="ck-run-config__row">
55
- <span class="ck-run-config__key">Created</span>
56
- <time datetime="<%= @run.created_at.iso8601 %>" data-local-time><%= @run.created_at.utc.strftime("%Y-%m-%d %H:%M UTC") %></time>
57
- </div>
58
- <div class="ck-run-config__row">
59
- <span class="ck-run-config__key">Dataset</span>
60
- <% if @run.dataset %>
61
- <span class="ck-run-config__dataset">
62
- <%= link_to @run.dataset.name, dataset_path(@run.dataset), class: "ck-link" %>
63
- <span class="ck-run-config__dataset-meta"><%= @run.dataset.row_count %> rows</span>
64
- <button type="button" class="ck-run-config__dataset-preview" onclick="document.getElementById('dataset-preview-<%= @run.id %>').showModal()">Preview</button>
65
- </span>
66
- <% else %>
67
- <span class="ck-run-config__none">None</span>
68
- <% end %>
69
- </div>
70
- <% if @run.judge_model.present? %>
71
- <div class="ck-run-config__row">
72
- <span class="ck-run-config__key">Judge</span>
73
- <span style="text-transform: none;"><%= @run.judge_model %></span>
74
- <% unless @run.judge_configured? %>
75
- <span class="ck-run-config__warn">provider not configured</span>
76
- <% end %>
77
- </div>
78
- <% end %>
79
- <% if @run.metrics.any? %>
80
- <div class="ck-run-config__row">
81
- <span class="ck-run-config__key">Metrics</span>
82
- <span><%= @run.metrics.map { |m| link_to(m.name, metric_path(m), class: "ck-link") }.join(", ").html_safe %></span>
83
- </div>
84
- <% end %>
85
- <div class="ck-run-config__row">
86
- <span class="ck-run-config__key">Temperature</span>
87
- <span><%= @run.temperature %></span>
88
- <% if @run.temperature_ignored? %>
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>
90
- <% end %>
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>
103
- </div>
53
+ <%= render "run_config", run: @run %>
104
54
 
105
55
  <% if @run.prompt %>
106
56
  <div class="ck-prompt-preview">
@@ -0,0 +1,5 @@
1
+ class AddJudgeTemperatureIgnoredToRuns < ActiveRecord::Migration[8.0]
2
+ def change
3
+ add_column :completion_kit_runs, :judge_temperature_ignored, :boolean, default: false, null: false
4
+ end
5
+ end
@@ -1,3 +1,3 @@
1
1
  module CompletionKit
2
- VERSION = "0.28.34"
2
+ VERSION = "0.28.36"
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.34
4
+ version: 0.28.36
5
5
  platform: ruby
6
6
  authors:
7
7
  - Damien Bastin
@@ -373,6 +373,7 @@ files:
373
373
  - app/views/completion_kit/runs/_response_row.html.erb
374
374
  - app/views/completion_kit/runs/_responses_region.html.erb
375
375
  - app/views/completion_kit/runs/_row.html.erb
376
+ - app/views/completion_kit/runs/_run_config.html.erb
376
377
  - app/views/completion_kit/runs/_sort_toolbar.html.erb
377
378
  - app/views/completion_kit/runs/_status_header.html.erb
378
379
  - app/views/completion_kit/runs/_status_panel.html.erb
@@ -447,6 +448,7 @@ files:
447
448
  - db/migrate/20260728000001_add_max_tokens_to_completion_kit_runs.rb
448
449
  - db/migrate/20260730000001_add_judge_temperature_to_completion_kit_runs.rb
449
450
  - db/migrate/20260730000002_create_completion_kit_prompt_serves.rb
451
+ - db/migrate/20260804000001_add_judge_temperature_ignored_to_runs.rb
450
452
  - lib/completion-kit.rb
451
453
  - lib/completion_kit.rb
452
454
  - lib/completion_kit/concurrency_check.rb