Class: CompletionKit::MetricsController

Inherits:
ApplicationController show all
Includes:
TagFiltering
Defined in:
app/controllers/completion_kit/metrics_controller.rb

Constant Summary

Constants inherited from ApplicationController

ApplicationController::ONBOARDING_DISMISS_COOKIE

Instance Method Summary collapse

Instance Method Details

#adopt_starterObject



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'app/controllers/completion_kit/metrics_controller.rb', line 18

def adopt_starter
  starter = StarterMetrics.find(params[:key])
  return redirect_to(metrics_path, alert: "Unknown starter metric.") unless starter
  if Metric.exists?(name: starter.name)
    return redirect_to(metrics_path, alert: "A metric named \"#{starter.name}\" already exists.")
  end
  metric = Metric.create!(
    name: starter.name,
    instruction: starter.instruction,
    rubric_bands: starter.rubric_bands,
    metric_type: starter.metric_type || "llm_judge",
    check_config: starter.check_config
  )
  redirect_to metric_path(metric), notice: "Added the \"#{starter.name}\" starter. Tweak any band before you run a judge against it."
end

#createObject



70
71
72
73
74
75
76
77
78
# File 'app/controllers/completion_kit/metrics_controller.rb', line 70

def create
  @metric = Metric.new(metric_params)

  if @metric.save
    redirect_to metric_path(@metric), notice: "Metric was successfully created."
  else
    render :new, status: :unprocessable_entity
  end
end

#destroyObject



94
95
96
97
# File 'app/controllers/completion_kit/metrics_controller.rb', line 94

def destroy
  @metric.destroy
  redirect_to metrics_path, notice: "Metric was successfully destroyed."
end

#dismiss_starterObject



34
35
36
37
38
39
# File 'app/controllers/completion_kit/metrics_controller.rb', line 34

def dismiss_starter
  starter = StarterMetrics.find(params[:key])
  return redirect_to(metrics_path, alert: "Unknown starter metric.") unless starter
  StarterMetricDismissal.find_or_create_by(starter_key: starter.key)
  redirect_to metrics_path, notice: "Dismissed \"#{starter.name}\". It won't appear here again."
end

#dismiss_suggestionObject



125
126
127
128
129
130
131
# File 'app/controllers/completion_kit/metrics_controller.rb', line 125

def dismiss_suggestion
  draft = MetricVersion.drafts.where(metric_id: @metric.id).find_by(id: params[:draft_id])
  label = draft&.version_label
  draft&.destroy
  target = params[:back_to] == "edit" ? edit_metric_path(@metric) : metric_path(@metric)
  redirect_to target, notice: label ? "Discarded draft #{label}." : "Draft already gone."
end

#editObject



58
59
60
61
62
63
64
65
66
67
68
# File 'app/controllers/completion_kit/metrics_controller.rb', line 58

def edit
  @suggestion_draft = MetricVersion.drafts.where(metric_id: @metric.id, source: "suggestion").order(created_at: :desc).first
  @edit_draft = MetricVersion.drafts.where(metric_id: @metric.id, source: "edit").order(created_at: :desc).first
  @published_metric_version = MetricVersion.published.where(metric_id: @metric.id, current: true).first
  @improve_disagreement_count = @metric.check? ? 0 : Agreement.where(metric_id: @metric.id, verdict: "disagree").count

  if @edit_draft
    @metric.instruction = @edit_draft.instruction
    @metric.rubric_bands = @edit_draft.rubric_bands
  end
end

#exclude_exampleObject



133
134
135
136
137
138
139
140
141
# File 'app/controllers/completion_kit/metrics_controller.rb', line 133

def exclude_example
  agreement = Agreement.where(metric_id: @metric.id).find(params[:agreement_id])
  agreement.update!(excluded_from_examples: true)
  render turbo_stream: turbo_stream.replace(
    "ck-guiding-#{@metric.id}",
    partial: "completion_kit/metrics/guiding_examples",
    locals: { metric: @metric, examples: MetricAgreementExamples.judge_examples_for(@metric) }
  )
end

#indexObject



7
8
9
10
11
# File 'app/controllers/completion_kit/metrics_controller.rb', line 7

def index
  @metrics = apply_tag_filter(Metric.includes(:metric_groups, :tags).order(:name))
  @available_starters = StarterMetrics.available
  @current_versions = MetricVersion.published.current.where(metric_id: @metrics.map(&:id)).index_by(&:metric_id)
end

#newObject



54
55
56
# File 'app/controllers/completion_kit/metrics_controller.rb', line 54

def new
  @metric = Metric.new
end

#publish_draftObject



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'app/controllers/completion_kit/metrics_controller.rb', line 143

def publish_draft
  scope = MetricVersion.where(metric_id: @metric.id)
  version = if params[:draft_id].present?
              scope.find_by(id: params[:draft_id])
            else
              MetricVersion.drafts.where(metric_id: @metric.id).order(created_at: :desc).first
            end

  if version.nil?
    redirect_to metric_path(@metric), alert: "No version to publish."
    return
  end

  was_published_already = version.published?
  reverting = was_published_already && !version.current?
  previously_current = MetricVersion.current.find_by(metric_id: @metric.id)

  version.publish!

  if reverting
    redirect_to metric_path(@metric),
                notice: "#{@metric.name} is back on #{version.version_label}. Its reviews count again; the ones you gave on #{previously_current.version_label} stay with that version."
  else
    redirect_to metric_path(@metric),
                notice: "#{@metric.name} #{version.version_label} is now the published version."
  end
end

#showObject



41
42
43
44
45
46
47
48
49
50
51
52
# File 'app/controllers/completion_kit/metrics_controller.rb', line 41

def show
  @edit_draft = MetricVersion.drafts.where(metric_id: @metric.id, source: "edit").order(created_at: :desc).first
  @suggestion_draft = MetricVersion.drafts.where(metric_id: @metric.id, source: "suggestion").order(created_at: :desc).first
  @versions = MetricVersion.where(metric_id: @metric.id).order(version_number: :desc).to_a
  if @metric.check?
    @improve_disagreement_count = 0
    @guiding_examples = []
  else
    @improve_disagreement_count = Agreement.where(metric_id: @metric.id, verdict: "disagree").count
    @guiding_examples = CompletionKit.config.judge_examples_from_reviews ? MetricAgreementExamples.judge_examples_for(@metric) : []
  end
end

#starter_previewObject



13
14
15
16
# File 'app/controllers/completion_kit/metrics_controller.rb', line 13

def starter_preview
  @starter = StarterMetrics.find(params[:key])
  return redirect_to(metrics_path, alert: "Unknown starter metric.") unless @starter
end

#suggest_variantsObject



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'app/controllers/completion_kit/metrics_controller.rb', line 99

def suggest_variants
  if @metric.check?
    redirect_to metric_path(@metric), alert: "Checks are exact, so there is nothing to suggest."
    return
  end

  target = params[:back_to] == "edit" ? edit_metric_path(@metric) : metric_path(@metric)
  counts = Agreement.where(metric_id: @metric.id, verdict: %w[agree disagree]).group(:verdict).count
  if counts["disagree"].to_i.zero?
    redirect_to target, alert: "Mark at least one case as Disagree before asking the model to suggest a change."
    return
  end

  MetricSuggestionJob.perform_later(@metric.id)

  if params[:back_to] == "edit"
    redirect_to metric_path(@metric), notice: "Drafting a change from your reviews. It will appear here once it's tested."
  else
    render turbo_stream: turbo_stream.replace(
      "ck-suggestion-status-#{@metric.id}",
      partial: "completion_kit/metrics/suggestion_pending",
      locals: { metric: @metric, count: counts.values.sum }
    )
  end
end

#updateObject



80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'app/controllers/completion_kit/metrics_controller.rb', line 80

def update
  meta_attrs = metric_params.except(:instruction, :rubric_bands, :check_config)

  unless @metric.update(meta_attrs)
    return render(:edit, status: :unprocessable_entity)
  end

  if @metric.check?
    update_check_definition
  else
    update_judge_definition
  end
end