132 lines
3.8 KiB
Elixir
132 lines
3.8 KiB
Elixir
defmodule Bright.VultrAI do
|
|
require Logger
|
|
@model "mistral-7b-v0.3"
|
|
@chat_endpoint "https://api.vultrinference.com/v1/chat/completions"
|
|
|
|
@doc """
|
|
This is not in-use due to less than stellar results. Keeping for future reference.
|
|
"""
|
|
def parse_social_post(raw_text, known_platforms) do
|
|
system_prompt = """
|
|
You are a social media post parser specializing in identifying livestream invitations and the platforms they are taking place on.
|
|
|
|
Analyze the following tweet and extract relevant information according to the JSON schema provided. Your response must be **valid JSON**.
|
|
|
|
## **Rules:**
|
|
1. **Title:** Use a short, relevant snippet from the tweet that represents the livestream event. If no livestream is mentioned, set the title as an empty string (`""`).
|
|
2. **Platforms:** Identify any livestream platforms mentioned in the tweet from this predefined list:
|
|
#{known_platforms}
|
|
- If none are found, return an empty array (`[]`).
|
|
|
|
## **Expected Response Schema**
|
|
|
|
#{expected_schema(known_platforms)}
|
|
|
|
"""
|
|
|
|
user_prompt = raw_text
|
|
|
|
request(@chat_endpoint, @model, system_prompt, user_prompt)
|
|
end
|
|
|
|
def expected_schema(known_platforms) do
|
|
%{
|
|
"type" => "object",
|
|
"properties" => %{
|
|
"title" => %{
|
|
"type" => "string",
|
|
"minLength" => 0
|
|
},
|
|
"platforms" => %{
|
|
"type" => "array",
|
|
"items" => %{
|
|
"type" => "string",
|
|
"enum" => known_platforms
|
|
},
|
|
"minItems" => 0,
|
|
"uniqueItems" => true
|
|
}
|
|
},
|
|
"required" => ["title", "platforms"],
|
|
"additionalProperties" => false
|
|
}
|
|
|> Jason.encode!()
|
|
end
|
|
|
|
def request(endpoint, model, system_prompt, user_prompt) do
|
|
api_key = Application.get_env(:bright, :vultr_ai_api_key)
|
|
|
|
headers = [
|
|
{"Authorization", "Bearer #{api_key}"},
|
|
{"Content-Type", "application/json"},
|
|
{"Accept", "Application/json; Charset=utf-8"}
|
|
]
|
|
|
|
body =
|
|
%{
|
|
messages: [
|
|
%{
|
|
role: "system",
|
|
content: system_prompt
|
|
},
|
|
%{
|
|
role: "user",
|
|
content: user_prompt
|
|
}
|
|
],
|
|
model: model,
|
|
stream: false,
|
|
max_tokens: 512,
|
|
n: 1,
|
|
seed: 0,
|
|
temperature: 1,
|
|
top_p: 1,
|
|
frequency_penalty: 0,
|
|
presence_penalty: 0,
|
|
logprobs: false
|
|
}
|
|
|> Jason.encode!()
|
|
|
|
case(HTTPoison.post(endpoint, body, headers)) do
|
|
{:ok, %HTTPoison.Response{status_code: 200, body: response_body}} ->
|
|
Logger.info("Successful VultrAI")
|
|
|
|
parse_response(response_body)
|
|
|
|
{:ok, %HTTPoison.Response{status_code: status_code, body: error_body}} ->
|
|
Logger.error("Failed VultrAI status=#{status_code}, error=#{error_body}")
|
|
|
|
{:error, %{status: status_code, body: error_body}}
|
|
|
|
{:error, %HTTPoison.Error{reason: reason}} ->
|
|
Logger.error("VultrAI HTTP request failed, reason=#{inspect(reason)}")
|
|
|
|
{:error, reason}
|
|
end
|
|
end
|
|
|
|
defp parse_response(response_body) do
|
|
with {:ok, decoded} <- Jason.decode(response_body),
|
|
{:ok, raw_content} <- extract_content(decoded),
|
|
{:ok, parsed_content} <- Jason.decode(raw_content) do
|
|
Logger.info("Successful VultrAI response")
|
|
Logger.debug(parsed_content)
|
|
{:ok, parsed_content}
|
|
else
|
|
error ->
|
|
log_and_return_error("Failed to parse response", error)
|
|
end
|
|
end
|
|
|
|
defp extract_content(%{"choices" => [%{"message" => %{"content" => content}} | _]}) do
|
|
{:ok, content}
|
|
end
|
|
|
|
defp extract_content(_), do: {:error, :invalid_response_format}
|
|
|
|
defp log_and_return_error(message, details) do
|
|
Logger.error("#{message}: #{inspect(details)}")
|
|
{:error, details}
|
|
end
|
|
end
|