Move all chat related code under chats
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user