From 96e2da629dcaaacb5ad0391c7a28e1657b6b6589 Mon Sep 17 00:00:00 2001 From: Dr Nic Williams Date: Tue, 19 Nov 2024 21:39:55 +1000 Subject: [PATCH 1/8] Home page is now a list of assistants --- app/controllers/application_controller.rb | 9 +++ app/controllers/assistants_controller.rb | 5 +- app/controllers/conversations_controller.rb | 8 --- app/views/assistants/_assistant.html.erb | 64 +++---------------- .../assistants/_assistant_sidebar.html.erb | 57 +++++++++++++++++ app/views/assistants/index.html.erb | 11 ++++ app/views/messages/_nav_column.html.erb | 18 +++++- .../controllers/assistants_controller_test.rb | 4 +- .../authenticate/by_http_header_test.rb | 3 - test/controllers/users_controller_test.rb | 9 ++- test/test_helper.rb | 1 - 11 files changed, 111 insertions(+), 78 deletions(-) create mode 100644 app/views/assistants/_assistant_sidebar.html.erb create mode 100644 app/views/assistants/index.html.erb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index e016ce3c2..34bf210e4 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -29,6 +29,15 @@ def redirect_to(*args) private + def set_nav_conversations + @nav_conversations = Conversation.grouped_by_increasing_time_interval_for_user(Current.user) + end + + def set_nav_assistants + @nav_assistants = Current.user.assistants.ordered + end + + def set_system_ivars @system_ivars = public_ivars end diff --git a/app/controllers/assistants_controller.rb b/app/controllers/assistants_controller.rb index 531517b0b..da171b6b2 100644 --- a/app/controllers/assistants_controller.rb +++ b/app/controllers/assistants_controller.rb @@ -1,6 +1,7 @@ class AssistantsController < ApplicationController + before_action :set_nav_conversations + before_action :set_nav_assistants + def index - assistant = Current.user.assistants.ordered.first - redirect_to new_assistant_message_path(assistant), status: :see_other end end diff --git a/app/controllers/conversations_controller.rb b/app/controllers/conversations_controller.rb index aeef68680..614826c24 100644 --- a/app/controllers/conversations_controller.rb +++ b/app/controllers/conversations_controller.rb @@ -28,14 +28,6 @@ def destroy private - def set_nav_conversations - @nav_conversations = Conversation.grouped_by_increasing_time_interval_for_user(Current.user) - end - - def set_nav_assistants - @nav_assistants = Current.user.assistants.ordered - end - def set_conversation @conversation = Current.user.conversations.find(params[:id]) end diff --git a/app/views/assistants/_assistant.html.erb b/app/views/assistants/_assistant.html.erb index 3e04f9fea..95123d9fc 100644 --- a/app/views/assistants/_assistant.html.erb +++ b/app/views/assistants/_assistant.html.erb @@ -1,58 +1,12 @@ -<%# locals: (assistant:, settings: true, assistant_counter: -1) %> -<% selected = assistant == @assistant %> -<% first = assistant_counter.zero? %> -<% visible = assistant_counter <= Assistant::MAX_LIST_DISPLAY-1 || selected %> -
- <%# This extra div ^ is needed because of the absolute positioning. It doesn't lay out properly if added to the div below. %> -
- <%= link_to new_assistant_message_path(assistant), class: "flex-1 flex py-1 items-center text-gray-950 dark:text-gray-100 font-medium truncate", data: { role: "name" } do %> - <%= render partial: "layouts/assistant_avatar", locals: { assistant: assistant, size: 7, classes: "mr-2" } %> - <%= assistant.name %> +
+
+ <%= render partial: "layouts/assistant_avatar", locals: { assistant: assistant, size: 7, classes: "border-none" } %> +
+
+ <%= link_to new_assistant_message_path(assistant), data: { role: "name" } do %> + +

<%= assistant.name %>

+

<%= assistant.description %>

<% end %> -
diff --git a/app/views/assistants/_assistant_sidebar.html.erb b/app/views/assistants/_assistant_sidebar.html.erb new file mode 100644 index 000000000..50ddcf80b --- /dev/null +++ b/app/views/assistants/_assistant_sidebar.html.erb @@ -0,0 +1,57 @@ +<%# locals: (assistant:, settings: true, assistant_counter: -1) %> +<% selected = assistant == @assistant %> +<% first = assistant_counter.zero? %> +<% visible = assistant_counter <= Assistant::MAX_LIST_DISPLAY-1 || selected %> +
+
+ <%= link_to new_assistant_message_path(assistant), class: "flex-1 flex py-1 items-center text-gray-950 dark:text-gray-100 font-medium truncate", data: { role: "name" } do %> + <%= render partial: "layouts/assistant_avatar", locals: { assistant: assistant, size: 7, classes: "mr-2" } %> + <%= assistant.name %> + <% end %> + +
+
diff --git a/app/views/assistants/index.html.erb b/app/views/assistants/index.html.erb new file mode 100644 index 000000000..f01e62ff7 --- /dev/null +++ b/app/views/assistants/index.html.erb @@ -0,0 +1,11 @@ +<%= content_for :nav_column do %> + <%= render 'messages/nav_column' %> +<% end %> + +
+

Assistants

+ +
+ <%= render @nav_assistants %> +
+
diff --git a/app/views/messages/_nav_column.html.erb b/app/views/messages/_nav_column.html.erb index 8b359a07e..2cafcc568 100644 --- a/app/views/messages/_nav_column.html.erb +++ b/app/views/messages/_nav_column.html.erb @@ -1,11 +1,25 @@ +
+ <%= link_to assistants_path, class: %| + flex + text-sm + rounded-lg + mb-1 p-1 pl-2 pr-2 mr-5 + hover:bg-gray-100 dark:hover:bg-gray-700 + pointer + | do %> + <%= icon "sparkles", variant: :outline %> + Assistants + <% end %> +
+
- <%= render @nav_assistants %> + <%= render partial: "assistants/assistant_sidebar", collection: @nav_assistants, as: :assistant %> <%= button_tag type: "button", class: %| diff --git a/test/controllers/assistants_controller_test.rb b/test/controllers/assistants_controller_test.rb index a421b5b92..634e59512 100644 --- a/test/controllers/assistants_controller_test.rb +++ b/test/controllers/assistants_controller_test.rb @@ -7,8 +7,8 @@ class AssistantsControllerTest < ActionDispatch::IntegrationTest login_as @user end - test "should get index" do + test "index shows assistants" do get assistants_url - assert_redirected_to new_assistant_message_path(@assistant) + assert_response :success end end diff --git a/test/controllers/concerns/authenticate/by_http_header_test.rb b/test/controllers/concerns/authenticate/by_http_header_test.rb index c4e04d4ee..8ec088eb9 100644 --- a/test/controllers/concerns/authenticate/by_http_header_test.rb +++ b/test/controllers/concerns/authenticate/by_http_header_test.rb @@ -103,9 +103,6 @@ class Authenticate::ByHttpHeaderTest < ActionDispatch::IntegrationTest private def assert_login_completed_for(user) - assert_response :redirect - assert_redirected_to new_assistant_message_path(user.assistants.ordered.first) - follow_redirect! assert_response :success assert_logged_in(user) end diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb index bce48c45f..d7b0af4c8 100644 --- a/test/controllers/users_controller_test.rb +++ b/test/controllers/users_controller_test.rb @@ -25,7 +25,6 @@ class UsersControllerTest < ActionDispatch::IntegrationTest post users_url, params: { person: { personable_type: "User", email: "azbshiri@gmail.com", personable_attributes: user_attr } } assert_response :redirect follow_redirect! - follow_redirect! # intentionally two redirects assert_response :success end @@ -51,7 +50,7 @@ class UsersControllerTest < ActionDispatch::IntegrationTest assert_match "Email can't be blank", response.body end - test "after create, an account should be bootstrapped and taken to a conversation" do + test "after create, an account should be bootstrapped and shown assistants" do email = "fake_email#{rand(1000)}@example.com" post users_url, params: { person: { personable_type: "User", email: email, personable_attributes: user_attr } } @@ -60,10 +59,10 @@ class UsersControllerTest < ActionDispatch::IntegrationTest assert_equal "Doe", user.last_name assert_equal 3, user.assistants.count, "This new user did not get the expected number of assistants" - assistant = user.assistants.ordered.first - + assert_redirected_to root_path follow_redirect! - assert_redirected_to new_assistant_message_path(assistant) + assert_response :success + assert_select "h1", "Assistants" end test "updates user preferences" do diff --git a/test/test_helper.rb b/test/test_helper.rb index 5c9d50662..4fae9bc64 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -34,7 +34,6 @@ def login_as(user_or_person, password = "secret") post login_path, params: { email: user.email, password: password } assert_response :redirect follow_redirect! # root - follow_redirect! # conversation assert_response :success end From 190273061fd8a0983ddd9ebc6cddb69df8ac7e72 Mon Sep 17 00:00:00 2001 From: Dr Nic Williams Date: Wed, 20 Nov 2024 15:55:39 +1000 Subject: [PATCH 2/8] Dedicated assistants page is a feature --- app/controllers/assistants_controller.rb | 5 ++ app/views/messages/_nav_column.html.erb | 28 +++++----- config/options.yml | 1 + .../controllers/assistants_controller_test.rb | 13 ++++- .../authenticate/by_http_header_test.rb | 12 +++-- test/controllers/users_controller_test.rb | 51 +++++++++++++------ test/test_helper.rb | 3 ++ 7 files changed, 80 insertions(+), 33 deletions(-) diff --git a/app/controllers/assistants_controller.rb b/app/controllers/assistants_controller.rb index da171b6b2..b4d3d2339 100644 --- a/app/controllers/assistants_controller.rb +++ b/app/controllers/assistants_controller.rb @@ -3,5 +3,10 @@ class AssistantsController < ApplicationController before_action :set_nav_assistants def index + unless Feature.assistants_page? + best_assistant = @nav_assistants.first + redirect_to new_assistant_message_path(best_assistant), status: :see_other + return + end end end diff --git a/app/views/messages/_nav_column.html.erb b/app/views/messages/_nav_column.html.erb index 2cafcc568..9103c3e61 100644 --- a/app/views/messages/_nav_column.html.erb +++ b/app/views/messages/_nav_column.html.erb @@ -1,16 +1,18 @@ -
- <%= link_to assistants_path, class: %| - flex - text-sm - rounded-lg - mb-1 p-1 pl-2 pr-2 mr-5 - hover:bg-gray-100 dark:hover:bg-gray-700 - pointer - | do %> - <%= icon "sparkles", variant: :outline %> - Assistants - <% end %> -
+<% if Feature.assistants_page? %> +
+ <%= link_to assistants_path, class: %| + flex + text-sm + rounded-lg + mb-1 p-1 pl-2 pr-2 mr-5 + hover:bg-gray-100 dark:hover:bg-gray-700 + pointer + | do %> + <%= icon "sparkles", variant: :outline %> + Assistants + <% end %> +
+<% end %>
email: <%= ENV["EMAIL_FEATURE"] || default_to(false, except_env_test: true) %> password_reset_email: <%= ENV["PASSWORD_RESET_EMAIL_FEATURE"] || default_to(false, except_env_test: true) %> + assistants_page: <%= ENV["ASSISTANTS_PAGE_FEATURE"] || false %> settings: # Be sure to add these ENV to docker-compose.yml app_url_protocol: <%= ENV["APP_URL_PROTOCOL"] || default_to(app_url: :protocol) %> diff --git a/test/controllers/assistants_controller_test.rb b/test/controllers/assistants_controller_test.rb index 634e59512..5b40621fc 100644 --- a/test/controllers/assistants_controller_test.rb +++ b/test/controllers/assistants_controller_test.rb @@ -7,8 +7,17 @@ class AssistantsControllerTest < ActionDispatch::IntegrationTest login_as @user end - test "index shows assistants" do - get assistants_url + test "index redirects to conversation if assistants_page is disabled" do + stub_features(assistants_page: false) do + get assistants_url + end + assert_redirected_to new_assistant_message_path(@assistant) + end + + test "index shows assistants if assistants_page is enabled" do + stub_features(assistants_page: true) do + get assistants_url + end assert_response :success end end diff --git a/test/controllers/concerns/authenticate/by_http_header_test.rb b/test/controllers/concerns/authenticate/by_http_header_test.rb index 8ec088eb9..7fccfac8f 100644 --- a/test/controllers/concerns/authenticate/by_http_header_test.rb +++ b/test/controllers/concerns/authenticate/by_http_header_test.rb @@ -2,14 +2,14 @@ class Authenticate::ByHttpHeaderTest < ActionDispatch::IntegrationTest test "should login user via header" do - stub_features(http_header_authentication: true) do + stub_features(http_header_authentication: true, assistants_page: false) do get root_url, headers: existing_http_auth_user assert_login_completed_for users(:rob) end end test "should create and login new user" do - stub_features(http_header_authentication: true, registration: true) do + stub_features(http_header_authentication: true, registration: true, assistants_page: false) do assert_difference "User.count", 1 do assert_difference "Person.count", 1 do get root_url, headers: new_http_auth_user @@ -53,6 +53,7 @@ class Authenticate::ByHttpHeaderTest < ActionDispatch::IntegrationTest test "should render unauthorized if no HTTP header present and no other auth is allowed" do stub_features( http_header_authentication: true, + assistants_page: false, password_authentication: false, google_authentication: false, microsoft_graph_authentication: false @@ -66,6 +67,7 @@ class Authenticate::ByHttpHeaderTest < ActionDispatch::IntegrationTest test "should render UN-AUTHORIZED if REGISTRATION DISABLED and NO HEADERS are provided and MANUAL AUTH IS DISABLED" do stub_features( http_header_authentication: true, # note: this disables manual auth (e.g. password, google) + assistants_page: false, ) do get root_url end @@ -79,7 +81,8 @@ class Authenticate::ByHttpHeaderTest < ActionDispatch::IntegrationTest stub_features( http_header_authentication: true, # note: this disables manual auth (e.g. password, google) - registration: false + registration: false, + assistants_page: false, ) do get root_url, headers: headers end @@ -103,6 +106,9 @@ class Authenticate::ByHttpHeaderTest < ActionDispatch::IntegrationTest private def assert_login_completed_for(user) + assert_response :redirect + assert_redirected_to new_assistant_message_path(user.assistants.ordered.first) + follow_redirect! assert_response :success assert_logged_in(user) end diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb index d7b0af4c8..8adee5cff 100644 --- a/test/controllers/users_controller_test.rb +++ b/test/controllers/users_controller_test.rb @@ -22,10 +22,12 @@ class UsersControllerTest < ActionDispatch::IntegrationTest end test "should create user" do - post users_url, params: { person: { personable_type: "User", email: "azbshiri@gmail.com", personable_attributes: user_attr } } - assert_response :redirect - follow_redirect! - assert_response :success + stub_features(assistants_page: true) do + post users_url, params: { person: { personable_type: "User", email: "azbshiri@gmail.com", personable_attributes: user_attr } } + assert_response :redirect + follow_redirect! + assert_response :success + end end test "should redirect back when the email address is already in use" do @@ -50,19 +52,38 @@ class UsersControllerTest < ActionDispatch::IntegrationTest assert_match "Email can't be blank", response.body end - test "after create, an account should be bootstrapped and shown assistants" do - email = "fake_email#{rand(1000)}@example.com" - post users_url, params: { person: { personable_type: "User", email: email, personable_attributes: user_attr } } + test "after create, an account should be bootstrapped and redirect to new conversation if assistants_page is disabled" do + stub_features(assistants_page: false) do + email = "fake_email#{rand(1000)}@example.com" + post users_url, params: { person: { personable_type: "User", email: email, personable_attributes: user_attr } } - user = Person.find_by(email: email).user - assert_equal "John", user.first_name - assert_equal "Doe", user.last_name - assert_equal 3, user.assistants.count, "This new user did not get the expected number of assistants" + user = Person.find_by(email: email).user + assert_equal "John", user.first_name + assert_equal "Doe", user.last_name + assert_equal 3, user.assistants.count, "This new user did not get the expected number of assistants" - assert_redirected_to root_path - follow_redirect! - assert_response :success - assert_select "h1", "Assistants" + assert_redirected_to root_path + follow_redirect! + assistant = user.assistants.ordered.first + assert_redirected_to new_assistant_message_path(assistant) + end + end + + test "after create, an account should be bootstrapped and shown assistants if assistants_page is enabled" do + stub_features(assistants_page: true) do + email = "fake_email#{rand(1000)}@example.com" + post users_url, params: { person: { personable_type: "User", email: email, personable_attributes: user_attr } } + + user = Person.find_by(email: email).user + assert_equal "John", user.first_name + assert_equal "Doe", user.last_name + assert_equal 3, user.assistants.count, "This new user did not get the expected number of assistants" + + assert_redirected_to root_path + follow_redirect! + assert_response :success + assert_select "h1", "Assistants" + end end test "updates user preferences" do diff --git a/test/test_helper.rb b/test/test_helper.rb index 4fae9bc64..052c6071c 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -34,6 +34,9 @@ def login_as(user_or_person, password = "secret") post login_path, params: { email: user.email, password: password } assert_response :redirect follow_redirect! # root + unless Feature.assistants_page? + follow_redirect! # conversation + end assert_response :success end From 90163f5c69afefc23a375ce9dc4501c4de544f52 Mon Sep 17 00:00:00 2001 From: Dr Nic Williams Date: Wed, 20 Nov 2024 16:05:24 +1000 Subject: [PATCH 3/8] Include a simple description for each default Assistant --- app/models/user/registerable.rb | 12 +++++++++--- app/views/assistants/index.html.erb | 2 +- .../concerns/authenticate/by_http_header_test.rb | 5 +++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/app/models/user/registerable.rb b/app/models/user/registerable.rb index 5795c50d1..b9286ee48 100644 --- a/app/models/user/registerable.rb +++ b/app/models/user/registerable.rb @@ -14,8 +14,14 @@ def create_initial_assistants_etc LanguageModel.import_from_file(users: [self]) - assistants.create! name: "GPT-4o", language_model: language_models.best_for_api_service(open_ai_api_service).first - assistants.create! name: "Claude 3.5 Sonnet", language_model: language_models.best_for_api_service(anthropic_api_service).first - assistants.create! name: "Meta Llama", language_model: language_models.best_for_api_service(groq_api_service).first + [ + ["GPT-4o", open_ai_api_service], + ["Claude 3.5 Sonnet", anthropic_api_service], + ["Meta Llama 3 70b", groq_api_service], + ].map do |name, api_service| + language_model = language_models.best_for_api_service(api_service).first + description = "Model #{language_model.api_name} on #{api_service.name}" + assistants.create! name:, description:, language_model: + end end end diff --git a/app/views/assistants/index.html.erb b/app/views/assistants/index.html.erb index f01e62ff7..14663b68d 100644 --- a/app/views/assistants/index.html.erb +++ b/app/views/assistants/index.html.erb @@ -5,7 +5,7 @@

Assistants

-
+
<%= render @nav_assistants %>
diff --git a/test/controllers/concerns/authenticate/by_http_header_test.rb b/test/controllers/concerns/authenticate/by_http_header_test.rb index 7fccfac8f..18b3d0493 100644 --- a/test/controllers/concerns/authenticate/by_http_header_test.rb +++ b/test/controllers/concerns/authenticate/by_http_header_test.rb @@ -28,7 +28,7 @@ class Authenticate::ByHttpHeaderTest < ActionDispatch::IntegrationTest end test "should create and login new user when NAME IS OMITTED" do - stub_features(http_header_authentication: true, registration: true) do + stub_features(http_header_authentication: true, registration: true, assistants_page: false) do assert_difference "User.count", 1 do assert_difference "Person.count", 1 do get root_url, headers: new_http_auth_user.except(Setting.http_header_auth_name) @@ -96,7 +96,8 @@ class Authenticate::ByHttpHeaderTest < ActionDispatch::IntegrationTest stub_features( http_header_authentication: true, - registration: false + registration: false, + assistants_page: false ) do get root_url, headers: headers end From d5adddd08bb2ebf9f84e77728c555aa9dee0b5f5 Mon Sep 17 00:00:00 2001 From: Dr Nic Williams Date: Wed, 20 Nov 2024 16:08:31 +1000 Subject: [PATCH 4/8] More whitespace on header --- app/views/assistants/index.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/assistants/index.html.erb b/app/views/assistants/index.html.erb index 14663b68d..0ac302db3 100644 --- a/app/views/assistants/index.html.erb +++ b/app/views/assistants/index.html.erb @@ -3,7 +3,7 @@ <% end %>
-

Assistants

+

Assistants

<%= render @nav_assistants %> From 8deec945ff9b8b06d0c656669e2ca13fdf9de99b Mon Sep 17 00:00:00 2001 From: Dr Nic Williams Date: Wed, 27 Nov 2024 08:08:18 +1000 Subject: [PATCH 5/8] Less flakey export tests --- test/models/language_model/export_test.rb | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/test/models/language_model/export_test.rb b/test/models/language_model/export_test.rb index dd4e00585..c67829c78 100644 --- a/test/models/language_model/export_test.rb +++ b/test/models/language_model/export_test.rb @@ -76,14 +76,16 @@ class LanguageModel::ExportTest < ActiveSupport::TestCase end test "import_from_file with existing models by api_name" do - model = users(:rob).language_models.not_deleted.first + user = users(:rob) + api_name = "gpt-4o" + model = user.language_models.find_by(api_name:) models = [{ - api_name: model.api_name, + api_name:, name: "new name", supports_images: false, supports_tools: true, - input_token_cost_cents: 0.0001, - output_token_cost_cents: 0.0001 + input_token_cost_cents: 0.1234, + output_token_cost_cents: 0.5678 }] storage = { "models" => models @@ -91,13 +93,13 @@ class LanguageModel::ExportTest < ActiveSupport::TestCase path = Rails.root.join("tmp/newmodels.yml") File.write(path, storage.to_yaml) assert_no_difference "LanguageModel.count" do - LanguageModel.import_from_file(path:, users: users(:rob)) + LanguageModel.import_from_file(path:, users: [user]) end model.reload assert_equal "new name", model.name assert_equal false, model.supports_images assert_equal true, model.supports_tools - assert_equal 0.0001, model.input_token_cost_cents - assert_equal 0.0001, model.output_token_cost_cents + assert_equal 0.1234, model.input_token_cost_cents + assert_equal 0.5678, model.output_token_cost_cents end end From fa3cdcdecfaa4b2e0be145981b4c68e3b502a7d7 Mon Sep 17 00:00:00 2001 From: Dr Nic Williams Date: Wed, 27 Nov 2024 08:31:01 +1000 Subject: [PATCH 6/8] Rename partials --- Gemfile | 1 - app/views/assistants/_assistant.html.erb | 63 ++++++++++++++++--- .../assistants/_assistant_index.html.erb | 12 ++++ .../assistants/_assistant_sidebar.html.erb | 57 ----------------- app/views/assistants/index.html.erb | 2 +- app/views/messages/_nav_column.html.erb | 2 +- 6 files changed, 68 insertions(+), 69 deletions(-) create mode 100644 app/views/assistants/_assistant_index.html.erb delete mode 100644 app/views/assistants/_assistant_sidebar.html.erb diff --git a/Gemfile b/Gemfile index b4dbd5b42..757ec18a2 100644 --- a/Gemfile +++ b/Gemfile @@ -13,7 +13,6 @@ gem "turbo-rails", "~> 2.0.5" gem "stimulus-rails", "~> 1.3.3" gem "tailwindcss-rails", "~> 2.7.2" gem "rack-cors" -gem "ostruct" # Build JSON APIs with ease [https://github.com/rails/jbuilder] # gem "jbuilder" diff --git a/app/views/assistants/_assistant.html.erb b/app/views/assistants/_assistant.html.erb index 95123d9fc..50ddcf80b 100644 --- a/app/views/assistants/_assistant.html.erb +++ b/app/views/assistants/_assistant.html.erb @@ -1,12 +1,57 @@ -
-
- <%= render partial: "layouts/assistant_avatar", locals: { assistant: assistant, size: 7, classes: "border-none" } %> -
-
- <%= link_to new_assistant_message_path(assistant), data: { role: "name" } do %> - -

<%= assistant.name %>

-

<%= assistant.description %>

+<%# locals: (assistant:, settings: true, assistant_counter: -1) %> +<% selected = assistant == @assistant %> +<% first = assistant_counter.zero? %> +<% visible = assistant_counter <= Assistant::MAX_LIST_DISPLAY-1 || selected %> +
+
+ <%= link_to new_assistant_message_path(assistant), class: "flex-1 flex py-1 items-center text-gray-950 dark:text-gray-100 font-medium truncate", data: { role: "name" } do %> + <%= render partial: "layouts/assistant_avatar", locals: { assistant: assistant, size: 7, classes: "mr-2" } %> + <%= assistant.name %> <% end %> +
diff --git a/app/views/assistants/_assistant_index.html.erb b/app/views/assistants/_assistant_index.html.erb new file mode 100644 index 000000000..9a2e5d008 --- /dev/null +++ b/app/views/assistants/_assistant_index.html.erb @@ -0,0 +1,12 @@ +
+
+ <%= render partial: "layouts/assistant_avatar", locals: { assistant:, size: 7, classes: "border-none" } %> +
+
+ <%= link_to new_assistant_message_path(assistant), data: { role: "name" } do %> + +

<%= assistant.name %>

+

<%= assistant.description %>

+ <% end %> +
+
diff --git a/app/views/assistants/_assistant_sidebar.html.erb b/app/views/assistants/_assistant_sidebar.html.erb deleted file mode 100644 index 50ddcf80b..000000000 --- a/app/views/assistants/_assistant_sidebar.html.erb +++ /dev/null @@ -1,57 +0,0 @@ -<%# locals: (assistant:, settings: true, assistant_counter: -1) %> -<% selected = assistant == @assistant %> -<% first = assistant_counter.zero? %> -<% visible = assistant_counter <= Assistant::MAX_LIST_DISPLAY-1 || selected %> -
-
- <%= link_to new_assistant_message_path(assistant), class: "flex-1 flex py-1 items-center text-gray-950 dark:text-gray-100 font-medium truncate", data: { role: "name" } do %> - <%= render partial: "layouts/assistant_avatar", locals: { assistant: assistant, size: 7, classes: "mr-2" } %> - <%= assistant.name %> - <% end %> - -
-
diff --git a/app/views/assistants/index.html.erb b/app/views/assistants/index.html.erb index 0ac302db3..37e56075d 100644 --- a/app/views/assistants/index.html.erb +++ b/app/views/assistants/index.html.erb @@ -6,6 +6,6 @@

Assistants

- <%= render @nav_assistants %> + <%= render partial: "assistant_index", collection: @nav_assistants, as: :assistant %>
diff --git a/app/views/messages/_nav_column.html.erb b/app/views/messages/_nav_column.html.erb index 9103c3e61..8099e3661 100644 --- a/app/views/messages/_nav_column.html.erb +++ b/app/views/messages/_nav_column.html.erb @@ -21,7 +21,7 @@ data-transition-toggle-class="hidden" class="flex flex-col" > - <%= render partial: "assistants/assistant_sidebar", collection: @nav_assistants, as: :assistant %> + <%= render @nav_assistants %> <%= button_tag type: "button", class: %| From 17c91d31535d41117f9371d63cdfb1e45da8d438 Mon Sep 17 00:00:00 2001 From: Dr Nic Williams Date: Wed, 27 Nov 2024 08:32:25 +1000 Subject: [PATCH 7/8] Less flakey export tests --- test/models/language_model/export_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/models/language_model/export_test.rb b/test/models/language_model/export_test.rb index c67829c78..2ff272dc2 100644 --- a/test/models/language_model/export_test.rb +++ b/test/models/language_model/export_test.rb @@ -81,7 +81,7 @@ class LanguageModel::ExportTest < ActiveSupport::TestCase model = user.language_models.find_by(api_name:) models = [{ api_name:, - name: "new name", + name: "new model name", supports_images: false, supports_tools: true, input_token_cost_cents: 0.1234, @@ -96,7 +96,7 @@ class LanguageModel::ExportTest < ActiveSupport::TestCase LanguageModel.import_from_file(path:, users: [user]) end model.reload - assert_equal "new name", model.name + assert_equal "new model name", model.name assert_equal false, model.supports_images assert_equal true, model.supports_tools assert_equal 0.1234, model.input_token_cost_cents From e75584d21e7cb8dc91601b12cba55810844070cf Mon Sep 17 00:00:00 2001 From: Dr Nic Williams Date: Wed, 27 Nov 2024 09:01:03 +1000 Subject: [PATCH 8/8] Improvements to sticky top nav item --- app/views/assistants/_assistant.html.erb | 16 +++++++++------- app/views/layouts/application.html.erb | 2 +- app/views/messages/_nav_column.html.erb | 18 +++++++++--------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/app/views/assistants/_assistant.html.erb b/app/views/assistants/_assistant.html.erb index 50ddcf80b..95f1aca35 100644 --- a/app/views/assistants/_assistant.html.erb +++ b/app/views/assistants/_assistant.html.erb @@ -1,8 +1,10 @@ <%# locals: (assistant:, settings: true, assistant_counter: -1) %> <% selected = assistant == @assistant %> -<% first = assistant_counter.zero? %> <% visible = assistant_counter <= Assistant::MAX_LIST_DISPLAY-1 || selected %> -
+
">
<%= link_to new_assistant_message_path(assistant), class: "flex-1 flex py-1 items-center text-gray-950 dark:text-gray-100 font-medium truncate", data: { role: "name" } do %> - <%= render partial: "layouts/assistant_avatar", locals: { assistant: assistant, size: 7, classes: "mr-2" } %> + <%= render partial: "layouts/assistant_avatar", locals: { assistant:, size: 7, classes: "mr-2" } %> <%= assistant.name %> <% end %>