Skip to content

Commit

Permalink
EN-7354 openai assistants are configured as active_records
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolas-entourage committed Nov 27, 2024
1 parent 4ea2e05 commit b82eb09
Show file tree
Hide file tree
Showing 13 changed files with 249 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
module Admin
class OpenaiAssistantConfigurationsController < Admin::BaseController
layout 'admin_large'

before_action :set_openai_assistant_configuration, only: [:edit, :update]

def index
@openai_assistant_configurations = OpenaiAssistantConfiguration.all
.order(:version)
.page(page)
.per(per)
end

def edit
end

def update
@openai_assistant_configuration.assign_attributes(openai_assistant_configuration_params)

if @openai_assistant_configuration.save
redirect_to edit_admin_openai_assistant_configuration_path(@openai_assistant_configuration)
else
render :edit
end
end

private

def set_openai_assistant_configuration
@openai_assistant_configuration = OpenaiAssistantConfiguration.find(params[:id])
end

def openai_assistant_configuration_params
params.require(:openai_assistant_configuration).permit(:prompt, :days_for_actions, :days_for_outings, :poi_from_file, :resource_from_file)
end

def page
params[:page] || 1
end

def per
params[:per] || 25
end
end
end
2 changes: 2 additions & 0 deletions app/models/openai_assistant_configuration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class OpenaiAssistantConfiguration < ApplicationRecord
end
59 changes: 43 additions & 16 deletions app/services/matching_services/connect.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
module MatchingServices
class Connect
attr_reader :client, :callback, :assistant_id, :instance, :user
attr_reader :configuration, :client, :callback, :assistant_id, :instance, :user

class MatcherCallback < Callback
end

def initialize instance:
@callback = MatcherCallback.new

@client = OpenAI::Client.new(access_token: ENV['OPENAI_API_KEY'])
@assistant_id = ENV['OPENAI_API_ASSISTANT_ID_2']
@configuration = OpenaiAssistantConfiguration.find_by_version(1)

@client = OpenAI::Client.new(access_token: @configuration.api_key)
@assistant_id = @configuration.assistant_id

@instance = instance
@user = instance.user
Expand Down Expand Up @@ -71,22 +73,26 @@ def find_run_message(thread_id, run_id)
end

def user_message
{
role: "user",
content: [
{ type: "text", text: get_formatted_prompt },
{ type: "text", text: get_recommandations.to_json }
]
}
end

def get_formatted_prompt
instance_class = if instance.respond_to?(:action) && instance.action?
instance.contribution? ? 'contribution' : 'solicitation'
else
instance.class.name.camelize.downcase
end

{
role: "user",
content: [{
type: "text",
text: "I created a #{instance_class} \"#{instance.name}\" : #{instance.description}. What are the most relevant recommandations? The following text contains all the possible recommandations."
}, {
type: "text",
text: get_recommandations.to_json
}]
}
@configuration.prompt
.gsub("{{action_type}}", instance_class)
.gsub("{{name}}", instance.name)
.gsub("{{description}}", instance.description)
end

def get_recommandations
Expand All @@ -102,17 +108,38 @@ def get_recommandations
def get_contributions
return [] if instance.is_a?(Entourage) && instance.contribution?

ContributionServices::Finder.new(user, Hash.new).find_all.limit(100)
ContributionServices::Finder.new(user, Hash.new)
.find_all
.where("created_at > ?", @configuration.days_for_actions.days.ago)
.limit(100)
end

def get_solicitations
return [] if instance.is_a?(Entourage) && instance.solicitation?

SolicitationServices::Finder.new(user, Hash.new).find_all.limit(100)
SolicitationServices::Finder.new(user, Hash.new)
.find_all
.where("created_at > ?", @configuration.days_for_actions.days.ago)
.limit(100)
end

def get_outings
OutingsServices::Finder.new(user, Hash.new).find_all.limit(100)
OutingsServices::Finder.new(user, Hash.new)
.find_all
.between(Time.zone.now, @configuration.days_for_outings.days.from_now)
.limit(100)
end

def get_pois
return unless @configuration.poi_from_file

Poi.validated.around(instance.latitude, instance.longitude, user.travel_distance).limit(300)
end

def get_resources
return unless @configuration.resource_from_file

Resource.where(status: :active)
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<div class="row">
<ol class="breadcrumb">
<li><%= link_to "openai_assistant_configurations", admin_openai_assistant_configurations_path %></li>
<li class="active">Modifier</li>
<li style="float: right;">
Version <%= @openai_assistant_configuration.version %>
</li>
</ol>

<h2>
<span class="text-muted"># Version <%= @openai_assistant_configuration.version %></span>
</h2>
</div>
50 changes: 50 additions & 0 deletions app/views/admin/openai_assistant_configurations/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<style>
.field_with_errors { display: inline-block }
</style>

<%= render partial: 'common/errors', locals: { obj: @openai_assistant_configuration } %>

<%= form_for [:admin, @openai_assistant_configuration], html: { role: "form" } do |f| %>
<div class="form-group">
<%= f.label :prompt %>
<div class="controls">
<%= f.text_area :prompt, class: "form-control", required: true %>
</div>
<i>{{action_type}} : en fonction de l'action créée par l'utilisateur, sera remplacé par "contribution" ou "solicitation"</i><br/>
<i>{{name}} : nom de l'action créée par l'utilisateur</i><br/>
<i>{{description}} : description de l'action créée par l'utilisateur</i><br/>
</div>

<div class="form-group">
<%= f.label :days_for_actions %>
<div class="controls">
<%= f.number_field :days_for_actions, class: "form-control", required: true %>
</div>
</div>

<div class="form-group">
<%= f.label :days_for_outings %>
<div class="controls">
<%= f.number_field :days_for_outings, class: "form-control", required: true %>
</div>
</div>

<div class="form-group">
<%= f.label :poi_from_file, "Charger les points d'intérêt depuis un fichier ?" %>
<div class="controls">
<%= f.radio_button :poi_from_file, true %> Oui
<%= f.radio_button :poi_from_file, false %> Non
</div>
</div>

<div class="form-group">
<%= f.label :resource_from_file, "Charger les ressources pédagogiques depuis un fichier ?" %>
<div class="controls">
<%= f.radio_button :resource_from_file, true %> Oui
<%= f.radio_button :resource_from_file, false %> Non
</div>
</div>

<%= f.submit 'Enregistrer', class: "btn btn-primary" %>
<%= link_to "Retour", admin_openai_assistant_configurations_path, class: "btn btn-default" %>
<% end %>
4 changes: 4 additions & 0 deletions app/views/admin/openai_assistant_configurations/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<div class="container">
<%= render 'edit_header', tab: :edit %>
<%= render partial: 'form' %>
</div>
36 changes: 36 additions & 0 deletions app/views/admin/openai_assistant_configurations/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<div class="container">
<div style="margin: auto">
<h1>openai_assistant_configuration</h1>

<div class="row">
<% unless @openai_assistant_configurations.none? %>
<table class="table custom-table">
<thead>
<th>Version</th>
<th>Prompt</th>
<th>poi_from_file</th>
<th>resource_from_file</th>
<th>days_for_actions</th>
<th>days_for_outings</th>
</thead>
<% @openai_assistant_configurations.each_with_index do |openai_assistant_configuration, i| %>
<% parite = i.even? ? 'pair' : 'impair' %>

<tr class="above-row row-<%= parite %>">
<td><%= link_to openai_assistant_configuration.version, edit_admin_openai_assistant_configuration_path(openai_assistant_configuration) %></td>
<td><%= link_to openai_assistant_configuration.prompt, edit_admin_openai_assistant_configuration_path(openai_assistant_configuration) %></td>
<td><%= openai_assistant_configuration.poi_from_file %></td>
<td><%= openai_assistant_configuration.resource_from_file %></td>
<td><%= openai_assistant_configuration.days_for_actions %></td>
<td><%= openai_assistant_configuration.days_for_outings %></td>
<% end %>
</table>
<% end %>
</div>

<%= page_entries_info @openai_assistant_configurations, entry_name: 'openai_assistant_configurations' %>
<div class="container">
<%= paginate(@openai_assistant_configurations) %>
</div>
</div>
</div>
1 change: 1 addition & 0 deletions app/views/layouts/_admin_header.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
Superadmin
</a>
<ul class="dropdown-menu">
<li><%= link_to "openai_assistant_configurations", admin_openai_assistant_configurations_path %></li>
<li><%= link_to "Options", admin_options_path %></li>
<li><%= link_to "Soliguide", admin_super_admin_soliguide_path %></li>
<li><%= link_to "Sidekiq", sidekiq_web_path %></li>
Expand Down
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@
end
end

resources :openai_assistant_configurations, only: [:index, :edit, :update]

resources :recommandations do
member do
get '/edit/image', action: :edit_image
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class CreateOpenaiAssistantConfigurations < ActiveRecord::Migration[6.1]
def change
create_table :openai_assistant_configurations do |t|
t.integer :version, unique: true
t.string :api_key, null: false
t.string :assistant_id, null: false

t.text :prompt, null: false

t.boolean :poi_from_file, default: false
t.boolean :resource_from_file, default: false

t.integer :days_for_actions, default: 30
t.integer :days_for_outings, default: 30

t.timestamps null: false
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class CreateOpenaiAssistantConfigurationInstance < ActiveRecord::Migration[6.1]
def change
unless Rails.env.test?
prompt = "I created a {{action_type}} \"{{name}}\" : {{description}}. What are the most relevant recommandations? The following text contains all the possible recommandations."

OpenaiAssistantConfiguration.new(
version: 1,
api_key: ENV['OPENAI_API_KEY'],
assistant_id: ENV['OPENAI_API_ASSISTANT_ID'],
prompt: prompt,
poi_from_file: true,
resource_from_file: true,
days_for_actions: 30,
days_for_outings: 30
).save
end
end
end
13 changes: 13 additions & 0 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,19 @@
t.index ["user_id"], name: "index_old_user_denorms_on_user_id"
end

create_table "openai_assistant_configurations", force: :cascade do |t|
t.integer "version"
t.string "api_key", null: false
t.string "assistant_id", null: false
t.text "prompt", null: false
t.boolean "poi_from_file", default: false
t.boolean "resource_from_file", default: false
t.integer "days_for_actions", default: 30
t.integer "days_for_outings", default: 30
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end

create_table "openai_assistants", force: :cascade do |t|
t.string "instance_type", null: false
t.integer "instance_id", null: false
Expand Down
3 changes: 3 additions & 0 deletions spec/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
# deactivate salesforce updates
SalesforceJob.any_instance.stub(:perform).and_return(nil)

# deactivate openai assistant
OpenaiAssistantJob.any_instance.stub(:perform).and_return(nil)

# deactivate translation on create
# TranslationObserver.any_instance.stub(:action).and_return(nil)
[ChatMessage, Entourage, Neighborhood].each do |klass|
Expand Down

0 comments on commit b82eb09

Please sign in to comment.