diff --git a/lib/bds/ai.ex b/lib/bds/ai.ex
index 98ed299..b6d685d 100644
--- a/lib/bds/ai.ex
+++ b/lib/bds/ai.ex
@@ -169,6 +169,9 @@ defmodule BDS.AI do
@spec available_chat_models(String.t() | nil) :: [map()]
defdelegate available_chat_models(current_model \\ nil), to: Chat
+ @spec effective_chat_model(BDS.AI.ChatConversation.t() | map() | nil) :: String.t() | nil
+ defdelegate effective_chat_model(conversation), to: Chat
+
@spec set_conversation_model(String.t(), String.t()) ::
{:ok, map()} | {:error, :not_found | Ecto.Changeset.t()}
defdelegate set_conversation_model(conversation_id, model_id), to: Chat
diff --git a/lib/bds/ai/chat.ex b/lib/bds/ai/chat.ex
index cb023e6..ea05e13 100644
--- a/lib/bds/ai/chat.ex
+++ b/lib/bds/ai/chat.ex
@@ -105,6 +105,15 @@ defmodule BDS.AI.Chat do
end)
end
+ @spec effective_chat_model(ChatConversation.t() | map() | nil) :: String.t() | nil
+ def effective_chat_model(%ChatConversation{} = conversation) do
+ resolve_effective_chat_model(conversation.model)
+ end
+
+ def effective_chat_model(%{model: model}), do: resolve_effective_chat_model(model)
+ def effective_chat_model(%{"model" => model}), do: resolve_effective_chat_model(model)
+ def effective_chat_model(_conversation), do: resolve_effective_chat_model(nil)
+
@spec set_conversation_model(String.t(), String.t()) ::
{:ok, map()} | {:error, :not_found | Ecto.Changeset.t()}
def set_conversation_model(conversation_id, model_id)
@@ -282,6 +291,25 @@ defmodule BDS.AI.Chat do
end
end
+ defp resolve_effective_chat_model(model) when is_binary(model) and model != "", do: model
+
+ defp resolve_effective_chat_model(_model) do
+ mode = if AI.airplane_mode?(), do: :airplane, else: :online
+
+ preference_key = if mode == :airplane, do: :airplane_chat, else: :chat
+
+ case Runtime.model_preference_value(preference_key) do
+ model when is_binary(model) and model != "" ->
+ model
+
+ _other ->
+ case AI.get_endpoint(mode) do
+ {:ok, %{model: model}} when is_binary(model) and model != "" -> model
+ _other -> nil
+ end
+ end
+ end
+
defp catalog_provider_name_map do
Repo.all(from provider in CatalogProvider, select: {provider.id, provider.name})
|> Map.new()
diff --git a/lib/bds/desktop/shell_live/chat_editor/message_build.ex b/lib/bds/desktop/shell_live/chat_editor/message_build.ex
index 3ef3348..6f2e39a 100644
--- a/lib/bds/desktop/shell_live/chat_editor/message_build.ex
+++ b/lib/bds/desktop/shell_live/chat_editor/message_build.ex
@@ -15,12 +15,14 @@ defmodule BDS.Desktop.ShellLive.ChatEditor.MessageBuild do
%ChatConversation{} = conversation ->
messages = AI.list_chat_messages(conversation.id)
request = Map.get(assigns.chat_editor_requests, conversation.id)
- available_models = AI.available_chat_models(conversation.model)
+ effective_model = AI.effective_chat_model(conversation)
+ available_models = AI.available_chat_models(effective_model)
%{
id: conversation.id,
title: conversation.title || translated("chat.newChat"),
model: conversation.model,
+ effective_model: effective_model,
available_models: available_models,
available_model_groups: ModelSelection.group_available_models(available_models),
model_selector_open?:
diff --git a/lib/bds/desktop/shell_live/chat_editor_html/chat_editor.html.heex b/lib/bds/desktop/shell_live/chat_editor_html/chat_editor.html.heex
index abcdd5c..1da9c52 100644
--- a/lib/bds/desktop/shell_live/chat_editor_html/chat_editor.html.heex
+++ b/lib/bds/desktop/shell_live/chat_editor_html/chat_editor.html.heex
@@ -17,7 +17,7 @@
phx-click="toggle_chat_model_selector"
data-testid="chat-model-selector-button"
>
- <%= @chat_editor.model || translated("chat.newChat") %>
+ <%= @chat_editor.effective_model || translated("chat.modelUnavailable") %>
▾
@@ -33,7 +33,7 @@