diff --git a/app/controllers/settings/language_models_controller.rb b/app/controllers/settings/language_models_controller.rb
index 7dde2fdd..5e0af71d 100644
--- a/app/controllers/settings/language_models_controller.rb
+++ b/app/controllers/settings/language_models_controller.rb
@@ -63,6 +63,6 @@ def set_system_language_model
end
def language_model_params
- params.require(:language_model).permit(:api_name, :name, :best, :supports_images, :supports_tools, :api_service_id, :supports_system_message, :supports_pdf)
+ params.require(:language_model).permit(:api_name, :name, :supports_images, :supports_tools, :api_service_id, :supports_system_message, :supports_pdf)
end
end
diff --git a/app/models/language_model.rb b/app/models/language_model.rb
index ffd44bb0..b9b8e539 100644
--- a/app/models/language_model.rb
+++ b/app/models/language_model.rb
@@ -13,11 +13,9 @@ class LanguageModel < ApplicationRecord
validates :api_name, :name, :position, presence: true
before_save :soft_delete_assistants, if: -> { has_attribute?(:deleted_at) && deleted_at && deleted_at_changed? && deleted_at_was.nil? }
- after_save :update_best_language_model_for_api_service
- scope :ordered, -> { order(Arel.sql("CASE WHEN best THEN 0 ELSE position END")).order(:position) }
+ scope :ordered, -> { order(:position) }
scope :for_user, ->(user) { where(user_id: user.id).not_deleted }
- scope :best_for_api_service, ->(api_service) { where(best: true, api_service: api_service) }
delegate :ai_backend, to: :api_service
delegate :name, to: :api_service, prefix: true, allow_nil: true
@@ -45,11 +43,4 @@ def soft_delete_assistants
assistants.update_all(deleted_at: Time.current)
end
- # Only one best language model per API service
- def update_best_language_model_for_api_service
- if best?
- api_service.language_models.update_all(best: false)
- update_column(:best, true)
- end
- end
end
diff --git a/app/models/language_model/export.rb b/app/models/language_model/export.rb
index ee019076..843240a3 100644
--- a/app/models/language_model/export.rb
+++ b/app/models/language_model/export.rb
@@ -4,7 +4,6 @@ module LanguageModel::Export
DEFAULT_EXPORT_ONLY = %i[
api_name
name
- best
api_service_name
supports_images
supports_tools
diff --git a/app/services/ai_backend.rb b/app/services/ai_backend.rb
index 5f14342b..48a7c2f0 100644
--- a/app/services/ai_backend.rb
+++ b/app/services/ai_backend.rb
@@ -60,11 +60,11 @@ def self.test_language_model(language_model, api_name = nil)
def self.test_api_service(api_service, url = nil, token = nil)
url ||= api_service.url
token ||= api_service.effective_token
- language_model = LanguageModel.where(best: true, api_service: api_service).first
+ language_model = api_service.language_models.first
api_name = language_model.api_name unless language_model.nil?
return "Error: API key (token) is blank" if api_service.requires_token? && token.blank?
- return "Error: API name is blank. Define a best Language Model for this API service." if api_name.blank?
+ return "Error: API name is blank. Define a Language Model for this API service." if api_name.blank?
test_execute(url, token, api_name)
end
diff --git a/app/views/settings/language_models/_form.html.erb b/app/views/settings/language_models/_form.html.erb
index 584c4f1c..b14e1502 100644
--- a/app/views/settings/language_models/_form.html.erb
+++ b/app/views/settings/language_models/_form.html.erb
@@ -54,11 +54,6 @@
<% end %>
-
- <%= form.check_box :best %>
- <%= form.label :best, t('app.settings.language_models.form.best') %>
-
-
<%= form.check_box :supports_images %>
<%= form.label :supports_images, t('app.settings.language_models.form.supports_images') %>
diff --git a/app/views/settings/language_models/index.html.erb b/app/views/settings/language_models/index.html.erb
index ba87dae9..b308927c 100644
--- a/app/views/settings/language_models/index.html.erb
+++ b/app/views/settings/language_models/index.html.erb
@@ -15,7 +15,6 @@
| <%= t('app.settings.language_models.table.name') %> |
- <%= t('app.settings.language_models.table.best') %> |
<%= t('app.settings.language_models.table.description') %> |
<%= t('app.settings.language_models.table.api_service') %> |
<%= t('app.settings.language_models.table.supports_pdf') %> |
@@ -27,7 +26,6 @@
<%= turbo_frame_tag dom_id(language_model) do %>
| <%= language_model.api_name %> |
- <%= language_model.best? ? t('app.generic.yes', default: 'Yes') : t('app.generic.no', default: 'No') %> |
<%= language_model.name %> |
<%= n_a_if_blank(language_model.api_service.name) %> |
<%= language_model.supports_pdf? ? t('app.generic.yes', default: 'Yes') : t('app.generic.no', default: 'No') %> |
diff --git a/config/locales/de.yml b/config/locales/de.yml
index 0df195ad..4b55f4ab 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -61,7 +61,6 @@ de:
back: "Zurück"
table:
name: "API-Name"
- best: "Bestes?"
description: "Beschreibung"
api_service: "API-Dienst"
supports_pdf: "Unterstützt PDFs"
@@ -70,7 +69,6 @@ de:
api_name: "API-Name"
api_name_hint: "Wie in der API-Doku angegeben"
api_service: "API-Dienst"
- best: "Bestes?"
supports_images: "Unterstützt Bilder?"
supports_tools: "Unterstützt Tools (Function Calling)?"
supports_system_message: "Unterstützt Systemnachricht (Anweisungen)?"
diff --git a/config/locales/en.yml b/config/locales/en.yml
index d985939f..4ad45fce 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -90,7 +90,6 @@ en:
back: "Back"
table:
name: "API Name"
- best: "Best?"
description: "Description"
api_service: "API Service"
supports_pdf: "Supports PDFs"
@@ -99,7 +98,6 @@ en:
api_name: "API Name"
api_name_hint: "As specified in the API docs"
api_service: "API Service"
- best: "Best?"
supports_images: "Supports Images?"
supports_tools: "Supports Tools (Function Calling)?"
supports_system_message: "Supports System Message (Instructions)?"
diff --git a/db/migrate/20251020230241_remove_best_from_language_models.rb b/db/migrate/20251020230241_remove_best_from_language_models.rb
new file mode 100644
index 00000000..e31d4a43
--- /dev/null
+++ b/db/migrate/20251020230241_remove_best_from_language_models.rb
@@ -0,0 +1,5 @@
+class RemoveBestFromLanguageModels < ActiveRecord::Migration[8.0]
+ def change
+ remove_column :language_models, :best, :boolean
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index d037d995..483742c7 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[8.0].define(version: 2025_09_30_104155) do
+ActiveRecord::Schema[8.0].define(version: 2025_10_20_230241) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_catalog.plpgsql"
@@ -172,7 +172,6 @@
t.bigint "user_id", null: false
t.bigint "api_service_id"
t.boolean "supports_tools", default: false
- t.boolean "best", default: false
t.boolean "supports_system_message", default: false
t.boolean "supports_pdf", default: false, null: false
t.index ["api_service_id"], name: "index_language_models_on_api_service_id"
diff --git a/models.yml b/models.yml
index d7b88387..17da655e 100644
--- a/models.yml
+++ b/models.yml
@@ -4,251 +4,215 @@ models:
name: GPT-5 (latest)
supports_images: true
supports_tools: true
- best: false
supports_system_message: true
api_service_name: OpenAI
- api_name: gpt-4o
name: GPT-4o
supports_images: true
supports_tools: true
- best: true
supports_system_message: true
api_service_name: OpenAI
- api_name: claude-3-5-sonnet-20241022
name: Claude 3.5 Sonnet (latest)
supports_images: true
supports_tools: true
- best: true
supports_system_message: true
api_service_name: Anthropic
- api_name: deepseek-r1-distill-llama-70B
name: DeepSeek R1 Distill Llama 70B
supports_images: false
supports_tools: false
- best: true
supports_system_message: true
api_service_name: Groq
- api_name: llama-3.3-70b-versatile
name: Llama 3.3 70B Versatile 128k
supports_images: false
supports_tools: false
- best: true
supports_system_message: true
api_service_name: Groq
- api_name: gpt-4o-2024-08-06
name: GPT-4o Omni Multimodal (2024-08-06)
supports_images: true
supports_tools: true
- best: false
supports_system_message: true
api_service_name: OpenAI
- api_name: gpt-4o-2024-05-13
name: GPT-4o Omni Multimodal (2024-05-13)
supports_images: true
supports_tools: true
- best: false
supports_system_message: true
api_service_name: OpenAI
- api_name: gpt-4-turbo
name: GPT-4 Turbo with Vision (latest)
supports_images: true
supports_tools: true
- best: false
supports_system_message: true
api_service_name: OpenAI
- api_name: gpt-4-turbo-2024-04-09
name: GPT-4 Turbo with Vision (2024-04-09)
supports_images: true
supports_tools: true
- best: false
supports_system_message: true
api_service_name: OpenAI
- api_name: gpt-4-turbo-preview
name: GPT-4 Turbo Preview
supports_images: false
supports_tools: true
- best: false
supports_system_message: true
api_service_name: OpenAI
- api_name: gpt-4-0125-preview
name: GPT-4 Turbo Preview (2024-01-25)
supports_images: false
supports_tools: true
- best: false
supports_system_message: true
api_service_name: OpenAI
- api_name: gpt-4-1106-preview
name: GPT-4 Turbo Preview (2023-11-06)
supports_images: false
supports_tools: true
- best: false
supports_system_message: true
api_service_name: OpenAI
- api_name: gpt-4-vision-preview
name: GPT-4 Turbo with Vision Preview (2023-11-06)
supports_images: true
supports_tools: true
- best: false
supports_system_message: true
api_service_name: OpenAI
- api_name: gpt-4-1106-vision-preview
name: GPT-4 Turbo with Vision Preview (2023-11-06)
supports_images: true
supports_tools: true
- best: false
supports_system_message: true
api_service_name: OpenAI
- api_name: gpt-4
name: GPT-4 (latest)
supports_images: false
supports_tools: true
- best: false
supports_system_message: true
api_service_name: OpenAI
- api_name: gpt-4-0613
name: GPT-4 Snapshot improved function calling (2023-06-13)
supports_images: false
supports_tools: true
- best: false
supports_system_message: true
api_service_name: OpenAI
- api_name: gpt-3.5-turbo
name: GPT-3.5 Turbo (latest)
supports_images: false
supports_tools: true
- best: false
supports_system_message: true
api_service_name: OpenAI
- api_name: gpt-3.5-turbo-0125
name: GPT-3.5 Turbo (2022-01-25)
supports_images: false
supports_tools: true
- best: false
supports_system_message: true
api_service_name: OpenAI
- api_name: gpt-3.5-turbo-1106
name: GPT-3.5 Turbo (2022-11-06)
supports_images: false
supports_tools: true
- best: false
supports_system_message: true
api_service_name: OpenAI
- api_name: claude-3-5-sonnet-20240620
name: Claude 3.5 Sonnet (2024-06-20)
supports_images: true
supports_tools: true
- best: false
supports_system_message: true
api_service_name: Anthropic
- api_name: claude-3-opus-20240229
name: Claude 3 Opus (2024-02-29)
supports_images: true
supports_tools: true
- best: false
supports_system_message: true
api_service_name: Anthropic
- api_name: claude-3-sonnet-20240229
name: Claude 3 Sonnet (2024-02-29)
supports_images: true
supports_tools: true
- best: false
supports_system_message: true
api_service_name: Anthropic
- api_name: claude-3-haiku-20240307
name: Claude 3 Haiku (2024-03-07)
supports_images: true
supports_tools: true
- best: false
supports_system_message: true
api_service_name: Anthropic
- api_name: claude-2.1
name: Claude 2.1
supports_images: false
supports_tools: true
- best: false
supports_system_message: true
api_service_name: Anthropic
- api_name: claude-2.0
name: Claude 2.0
supports_images: false
supports_tools: true
- best: false
supports_system_message: true
api_service_name: Anthropic
- api_name: claude-instant-1.2
name: Claude Instant 1.2
supports_images: false
supports_tools: true
- best: false
supports_system_message: true
api_service_name: Anthropic
- api_name: llama3-70b-8192
name: Meta Llama 3 70b
supports_images: false
supports_tools: true
- best: false
supports_system_message: true
api_service_name: Groq
- api_name: llama3-8b-8192
name: Meta Llama 3 8b
supports_images: false
supports_tools: true
- best: false
supports_system_message: true
api_service_name: Groq
- api_name: mixtral-8x7b-32768
name: Mistral 8 7b
supports_images: false
supports_tools: true
- best: false
supports_system_message: true
api_service_name: Groq
- api_name: gemma-7b-it
name: Google Gemma 7b
supports_images: false
supports_tools: true
- best: false
supports_system_message: true
api_service_name: Groq
- api_name: gpt-3.5-turbo-instruct
name: GPT-3.5 Turbo Instruct
supports_images: false
supports_tools: false
- best: false
supports_system_message: false
api_service_name: OpenAI
- api_name: gpt-3.5-turbo-16k-0613
name: GPT-3.5 Turbo (2022-06-13)
supports_images: false
supports_tools: false
- best: false
supports_system_message: false
api_service_name: OpenAI
- api_name: gpt-4o-mini
name: GPT-4o Mini (latest)
supports_images: true
supports_tools: true
- best: false
supports_system_message: true
api_service_name: OpenAI
- api_name: o1-preview
name: OpenAI o1 (preview)
supports_images: false
supports_tools: true
- best: false
supports_system_message: true
api_service_name: OpenAI
- api_name: claude-3-5-haiku-20241022
name: Claude 3.5 Haiku (latest)
supports_images: false
supports_tools: true
- best: false
supports_system_message: true
api_service_name: Anthropic
- api_name: gemini-1.5-pro-002
name: Google Gemini Pro 1.5 (latest)
supports_images: true
supports_tools: false
- best: true
supports_system_message: true
api_service_name: Google Gemini
diff --git a/test/controllers/settings/language_models_controller_test.rb b/test/controllers/settings/language_models_controller_test.rb
index b886abe0..b5bc1dda 100644
--- a/test/controllers/settings/language_models_controller_test.rb
+++ b/test/controllers/settings/language_models_controller_test.rb
@@ -33,15 +33,14 @@ class Settings::LanguageModelsControllerTest < ActionDispatch::IntegrationTest
assert_equal @user, LanguageModel.last.user
end
- test "create new best language model replaces existing best" do
+ test "create new language model works" do
api_service = api_services(:keith_anthropic_service)
- assert_equal api_service.language_models.best.pluck(:api_name), ["claude-best"]
+ initial_count = api_service.language_models.count
params = {
api_name: "new-claude-service",
api_service_id: api_service.id,
- name: "new best service",
- best: true,
+ name: "new service",
supports_images: false,
supports_tools: false
}
@@ -51,8 +50,7 @@ class Settings::LanguageModelsControllerTest < ActionDispatch::IntegrationTest
end
assert_redirected_to settings_language_models_url
-
- assert_equal api_service.language_models.best.pluck(:api_name), ["new-claude-service"]
+ assert_equal initial_count + 1, api_service.language_models.count
end
test "should get edit" do
@@ -152,15 +150,16 @@ class Settings::LanguageModelsControllerTest < ActionDispatch::IntegrationTest
assert_equal params, @language_model.reload.slice(:api_name, :name, :supports_images)
end
- test "update should update best language model" do
+ test "update language model works" do
api_service = api_services(:keith_anthropic_service)
- assert_equal api_service.language_models.best.pluck(:api_name), ["claude-best"]
+ initial_count = api_service.language_models.count
another_language_model = language_models(:claude_3_opus_20240229)
- patch settings_language_model_url(another_language_model), params: { language_model: {best: true}}
+ patch settings_language_model_url(another_language_model), params: { language_model: {supports_images: true}}
assert_redirected_to settings_language_models_url
- assert_equal api_service.language_models.best.pluck(:api_name), ["claude-3-opus-20240229"]
+ assert another_language_model.reload.supports_images?
+ assert_equal initial_count, api_service.language_models.count
end
test "destroy should soft-delete language_model" do
diff --git a/test/fixtures/language_models.yml b/test/fixtures/language_models.yml
index 0f1b55ed..d0394c9b 100644
--- a/test/fixtures/language_models.yml
+++ b/test/fixtures/language_models.yml
@@ -5,7 +5,6 @@ gemini-1.5-pro-002:
name: Google Gemini 1.5 Pro (latest)
api_service: keith_gemini_service
api_name: gemini-1.5-pro-002
- best: true
supports_images: true
supports_tools: false
supports_system_message: true
@@ -124,7 +123,6 @@ gpt_best:
position: 1
user: keith
name: Best OpenAI Model
- best: true
api_name: gpt-best
api_service: keith_openai_service
supports_images: true
@@ -136,7 +134,6 @@ claude_best:
position: 2
user: keith
name: Best Anthropic Model
- best: true
api_service: keith_anthropic_service
api_name: claude-best
supports_images: true
diff --git a/test/models/api_service_test.rb b/test/models/api_service_test.rb
index 71b56685..bef223dd 100644
--- a/test/models/api_service_test.rb
+++ b/test/models/api_service_test.rb
@@ -40,7 +40,7 @@ class APIServiceTest < ActiveSupport::TestCase
assert_equal "new secret", api_service.token
end
- test "both ai_backends are specified for best models" do
+ test "both ai_backends are specified for language models" do
assert_equal AIBackend::OpenAI, language_models(:gpt_best).ai_backend
assert_equal AIBackend::Anthropic, language_models(:claude_best).ai_backend
end
diff --git a/test/models/language_model/export_test.rb b/test/models/language_model/export_test.rb
index 698b4f53..8d554231 100644
--- a/test/models/language_model/export_test.rb
+++ b/test/models/language_model/export_test.rb
@@ -21,7 +21,7 @@ class LanguageModel::ExportTest < ActiveSupport::TestCase
assert File.exist?(path)
storage = JSON.load_file(path)
models = storage["models"]
- assert_equal models.first.keys.sort, %w[api_name name best supports_images supports_tools supports_system_message api_service_name].sort
+ assert_equal models.first.keys.sort, %w[api_name name supports_images supports_tools supports_system_message api_service_name].sort
end
test "export_to_file yaml" do
@@ -30,7 +30,7 @@ class LanguageModel::ExportTest < ActiveSupport::TestCase
assert File.exist?(path)
storage = YAML.load_file(path)
models = storage["models"]
- assert_equal models.first.keys.sort, %w[api_name name best supports_images supports_tools supports_system_message api_service_name].sort
+ assert_equal models.first.keys.sort, %w[api_name name supports_images supports_tools supports_system_message api_service_name].sort
end
test "import_from_file with only new models" do