diff --git a/lib/search_web/controllers/page_controller.ex b/lib/search_web/controllers/page_controller.ex index d260396..670b1ae 100644 --- a/lib/search_web/controllers/page_controller.ex +++ b/lib/search_web/controllers/page_controller.ex @@ -1,13 +1,30 @@ defmodule SearchWeb.PageController do use SearchWeb, :controller + @empty_form Phoenix.Component.to_form(%{ + "search_text" => nil, + "k" => nil, + "embedding_model" => nil + }) + + @embedding_model_opts Search.Application.embedding_models() + |> Enum.map(&(&1 |> Module.split() |> Enum.reverse() |> Enum.at(0))) + def home(conn, _params) do # The home page is often custom made, # so skip the default app layout. - render(conn, :home, form: Phoenix.Component.to_form(%{"search_text" => nil, "k" => nil})) + render(conn, :home, form: @empty_form, embedding_models: @embedding_model_opts) end - def search(conn, %{"k" => k, "search_text" => search_text} = params) do + def search( + conn, + %{"k" => k, "search_text" => search_text, "embedding_model" => embedding_model} = params + ) do + model = + Enum.find(Search.Application.embedding_models(), fn mod -> + "Elixir.Search.Embeddings.#{embedding_model}" == "#{mod}" + end) + k = String.to_integer(k) search_text = String.trim(search_text) @@ -19,10 +36,14 @@ defmodule SearchWeb.PageController do end if errors == [] do - %{embedding: query_tensor} = Nx.Serving.batched_run(Search.Embedding, search_text) - fragments = Search.Fragment.knn_lookup(query_tensor, k: k) + %{embedding: query_tensor} = Nx.Serving.batched_run(model, search_text) + + items = + Search.Embeddings.knn_query(model, query_tensor, k: k) + |> Stream.map(& &1.doc_fragment.doc_item) + |> Enum.uniq_by(& &1.id) - render(conn, :search, fragments: fragments) + render(conn, :search, items: items) else render(conn, :home, form: Phoenix.Component.to_form(params, errors: errors)) end diff --git a/lib/search_web/controllers/page_html/home.html.heex b/lib/search_web/controllers/page_html/home.html.heex index e4931eb..7f38a16 100644 --- a/lib/search_web/controllers/page_html/home.html.heex +++ b/lib/search_web/controllers/page_html/home.html.heex @@ -1,6 +1,13 @@ <.simple_form for={@form} class="bg-transparent" action="/search" method="get"> <.input field={@form[:search_text]} label="Search prompt" required /> <.input field={@form[:k]} type="number" label="Number of entries" required min="1" value="10" /> + <.input + field={@form[:embedding_model]} + label="Embedding model" + type="select" + options={@embedding_models} + required + /> <:actions> <.button>Search diff --git a/lib/search_web/controllers/page_html/search.html.heex b/lib/search_web/controllers/page_html/search.html.heex index d2ecb4a..7a79cc5 100644 --- a/lib/search_web/controllers/page_html/search.html.heex +++ b/lib/search_web/controllers/page_html/search.html.heex @@ -1,3 +1,6 @@ -
<%= item.title %>
+ <%= if item.doc do %> + <%= raw(Earmark.as_html!(item.doc)) %> + <% end %>