Move all chat related code under chats

This commit is contained in:
Claudio Ortolina
2026-03-17 14:30:24 +00:00
parent 5eb7ccd837
commit 63c95ff1e2
8 changed files with 12 additions and 12 deletions
+50
View File
@@ -0,0 +1,50 @@
defmodule MusicLibrary.Chats.ArtistChat do
@moduledoc """
Chat implementation for artists using OpenAI streaming with Wikipedia context.
"""
@behaviour MusicLibrary.Chats.StreamProvider
alias MusicLibrary.Artists.ArtistInfo
@impl true
@spec stream_response([map()], {map(), ArtistInfo.t()}, (String.t() -> any())) ::
:ok | {:error, term()}
def stream_response(messages, {artist, artist_info}, callback) do
instructions = build_instructions(artist, artist_info)
OpenAI.chat_stream(messages, on_chunk: callback, instructions: instructions)
end
defp build_instructions(artist, artist_info) do
context = build_context(artist, artist_info)
"""
You are a knowledgeable music assistant. Answer questions about the artist \
the user is currently viewing. Use the provided artist information as your \
primary reference, and use web search to find additional up-to-date \
information when helpful. Be concise and accurate. When unsure, say so.
Artist information:
#{context}
"""
end
defp build_context(artist, artist_info) do
country = ArtistInfo.country(artist_info)
description = ArtistInfo.wikipedia_description(artist_info)
summary = ArtistInfo.wikipedia_summary(artist_info)
parts =
[
{"Name", artist.name},
{"Country", country.name},
{"Description", description},
{"Biography", summary}
]
|> Enum.reject(fn {_label, value} -> value in [nil, ""] end)
|> Enum.map_join("\n", fn {label, value} -> "#{label}: #{value}" end)
parts
end
end
+52
View File
@@ -0,0 +1,52 @@
defmodule MusicLibrary.Chats.RecordChat do
@moduledoc """
Chat implementation for records using OpenAI streaming with web search.
"""
@behaviour MusicLibrary.Chats.StreamProvider
alias MusicLibrary.Records.Record
@impl true
@spec stream_response([map()], {Record.t(), String.t() | nil}, (String.t() -> any())) ::
:ok | {:error, term()}
def stream_response(messages, {record, embedding_text}, callback) do
instructions = build_instructions(record, embedding_text)
OpenAI.chat_stream(messages, on_chunk: callback, instructions: instructions)
end
defp build_instructions(%Record{} = record, embedding_text) do
context =
case embedding_text do
nil -> basic_context(record)
"" -> basic_context(record)
text -> text
end
"""
You are a knowledgeable music assistant. Answer questions about the album \
the user is currently viewing. Use the provided album information as your \
primary reference, and use web search to find additional up-to-date \
information when helpful. Be concise and accurate. When unsure, say so.
Album information:
#{context}
"""
end
defp basic_context(%Record{} = record) do
artist_names = Record.artist_names(record)
genres = Enum.join(record.genres || [], ", ")
"""
Album: #{record.title}
Artists: #{artist_names}
Genres: #{genres}
Released: #{record.release_date || "Unknown"}
Type: #{record.type}
Format: #{record.format}
"""
|> String.trim()
end
end
@@ -0,0 +1,11 @@
defmodule MusicLibrary.Chats.StreamProvider do
@moduledoc """
Behaviour for streaming AI chat with entity-specific context.
"""
@callback stream_response(
messages :: list(map()),
context :: term(),
callback :: (String.t() -> any())
) :: :ok | {:error, term()}
end