Skip to content

Commit

Permalink
Merge pull request #169 from identity-research-lab/category-suggestio…
Browse files Browse the repository at this point in the history
…ns-2

Suggested categories
  • Loading branch information
CoralineAda authored Oct 31, 2024
2 parents a4585b7 + a670b74 commit cff69bb
Show file tree
Hide file tree
Showing 15 changed files with 171 additions and 30 deletions.
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ gem 'ruby-openai'
gem 'activegraph', '11.5.0.beta.3'
gem 'neo4j-ruby-driver'
gem 'yard'
gem 'csv'
gem 'ostruct'

# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
gem "rails", "~> 7.2.1"
Expand Down
6 changes: 5 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ GEM
fiber-local
json
crass (1.0.6)
csv (3.3.0)
date (3.3.4)
debug (1.9.2)
irb (~> 1.10)
Expand Down Expand Up @@ -185,6 +186,7 @@ GEM
nokogiri (1.16.7-x86_64-linux)
racc (~> 1.4)
orm_adapter (0.5.0)
ostruct (0.6.0)
pg (1.5.7)
pry (0.14.2)
coderay (~> 1.1)
Expand Down Expand Up @@ -334,10 +336,12 @@ DEPENDENCIES
activegraph (= 11.5.0.beta.3)
bootsnap
capybara
csv
debug
dotenv
faker (~> 3.4, >= 3.4.2)
neo4j-ruby-driver
ostruct
pg
pry
puma (>= 5.0)
Expand All @@ -356,7 +360,7 @@ DEPENDENCIES
yard

RUBY VERSION
ruby 3.2.2p53
ruby 3.3.5p100

BUNDLED WITH
2.5.6
52 changes: 52 additions & 0 deletions app/assets/stylesheets/icons.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion app/assets/stylesheets/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
ul,
ol {
list-style-position: inside;
margin: 1.5rem 0 1.5rem 1.5rem;
margin: 0 0 1.5rem 1.5rem;
}

em {
Expand Down
4 changes: 3 additions & 1 deletion app/controllers/categories_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ class CategoriesController < ApplicationController

def index
@section_name = @question.label
@context = @question.context
@categories = Category.where(context: @question.context.name).order(:name)
@enqueued_at = params[:enqueued_at].present? ? Time.at(params[:enqueued_at].to_i).strftime("%T %Z") : nil
end
Expand All @@ -14,7 +15,8 @@ def show
end

def new
@category = Category.new(name: "New Category", context: @question.context.name)
@category = Category.new(name: "New Category", context: @question.context.name)
@context = @question.context
end

def create
Expand Down
12 changes: 12 additions & 0 deletions app/controllers/codebooks_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,16 @@ def show

end

def enqueue_category_suggestions
question = Question.find(params[:codebook_id])
context = question.context
CategorySuggestionsJob.perform_async(context.id)
respond_to do |format|
format.turbo_stream do
render turbo_stream: turbo_stream.replace("frame-suggestions", partial: "/categories/suggestions", locals: { context: context, question: question, enqueued: params[:enqueued] })
end
end

end

end
15 changes: 15 additions & 0 deletions app/jobs/category_suggestions_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# This background job performs the Category derivation process.
class CategorySuggestionsJob

include Sidekiq::Job

queue_as :default

def perform(context_id)
Rails.logger.info("CategorySuggestionsJob running with context id #{context_id}")
return unless context = Context.find(context_id)
context.suggest_categories
context.update_attribute(:suggestions_updated_at, DateTime.now)
end

end
6 changes: 6 additions & 0 deletions app/models/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,10 @@ class Context < ApplicationRecord

has_many :questions

def suggest_categories
update_attribute(:suggested_categories, [])
categories = Services::SuggestCategories.perform(self.id).map{|category| category['category'] }
update_attribute(:suggested_categories, categories)
end

end
20 changes: 12 additions & 8 deletions app/models/services/suggest_categories.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Services
class SuggestCategories

attr_accessor :text
attr_accessor :context

# This is the prompt sent to the selected AI agent to provide instructions on category derivision.
PROMPT = %{
Expand All @@ -19,21 +19,25 @@ class SuggestCategories
]
}
The list of codes is:
The array of codes is:
}

def self.perform(text)
new(text).perform
def self.perform(context_id)
new(context_id).perform
end

def initialize(text)
@text = text
def initialize(context_id)
@context = Context.find(context_id)
end

# Uses the OpenAI client to pass the prompt and text through the API for sentiment analysis.
def perform
return false unless text.present?
response = Clients::OpenAi.request("#{PROMPT} #{text}")
return false unless context.present?
codes = Code.where(context: context.name).map(&:name)

response = Clients::OpenAi.request("#{PROMPT} #{codes}")
# response = { "categories" => [ { "category" => "divisions" }, { "category" => "third space" }, { "category" => "intergenerational" } ] }

return false unless response['categories'].present?
return response['categories']
end
Expand Down
23 changes: 23 additions & 0 deletions app/views/categories/_suggestions.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<%= turbo_frame_tag "frame-suggestions" do %>

<% if enqueued && DateTime.parse(enqueued) > context.suggestions_updated_at %>
<div class="throbber"><div></div><div></div></div>
<script language="javascript">
function refreshSpinner() {
setInterval(() => {
console.log("firing");
location.reload();
}, 3000);
}
refreshSpinner();
</script>
<% else %>
<ul>
<% context.suggested_categories.each do |suggestion| %>
<li><%= suggestion %></li>
<% end %>
</ul>
<%= button_to "Get Suggestions", codebook_enqueue_category_suggestions_path(question.id, params: { enqueued: DateTime.now }, method: :put, form: { data: { turbo: true, turbo_stream: true } } ) %>
<% end %>

<% end %>
6 changes: 1 addition & 5 deletions app/views/categories/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@
</div>

<h2>Suggested Categories:</h2>
<% if @enqueued_at %>
<p>Category suggestions were requested at <%= @enqueued_at %>. Please allow up to 2 minutes for the process to complete. You can reload the page to monitor progress.</p>
<% else %>
<%= button_to "Get Suggestions", codebook_enqueue_categories_path(@question.id, params: { enqueued: true }, method: :put ) %>
<% end %>
<%= render partial: "suggestions", locals: { context: @context, question: @question, enqueued: nil } %>

<%= render partial: "/shared/filtering" %>
41 changes: 29 additions & 12 deletions app/views/categories/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,32 @@

<h1>Add a Category</h1>

<%= form_with model: @category, url: question_categories_path(question_id: @question.id) do |f| %>
<fieldset>
<%= label :name, "Name" %>
<%= f.text_field :name %>
</fieldset>
<fieldset>
<%= label :description, "Description" %>
<%= f.text_area :description %>
</fieldset>
<%= f.hidden_field :context %>
<%= f.submit "Create" %>
<% end %>
<div class="two-column">

<div class="column">
<%= form_with model: @category, url: question_categories_path(question_id: @question.id) do |f| %>
<fieldset>
<%= label :name, "Name" %>
<%= f.text_field :name %>
</fieldset>
<fieldset>
<%= label :description, "Description" %>
<%= f.text_area :description %>
</fieldset>
<%= f.hidden_field :context %>
<%= f.submit "Create" %>
<% end %>
</div>

<% if @context.suggested_categories.any? %>
<div class="column">
<h2>Suggested categories:</h2>
<ul>
<% @context.suggested_categories.each do |suggestion| %>
<li><%= suggestion %></li>
<% end %>
</ul>
</div>
<% end %>

</div>
2 changes: 1 addition & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
resources :themes

resources :codebooks do
post "enqueue_categories", action: "enqueue_categories"
post "enqueue_category_suggestions", action: "enqueue_category_suggestions"
end

resources :questions do
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class AddSuggestedCategoriesToContext < ActiveRecord::Migration[7.2]
def change
add_column :contexts, :suggested_categories, :string, array: true, default: []
add_column :contexts, :suggestions_updated_at, :datetime
end
end
4 changes: 3 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit cff69bb

Please sign in to comment.