# Mysterious Crystal Ball ```elixir Mix.install( [ {:bumblebee, "~> 0.5.3"}, {:nx, "~> 0.7.0"}, {:exla, "~> 0.7.0"}, {:axon, "~> 0.6.1"}, {:kino, "~> 0.12.0"}, {:req, "~> 0.4.11"}, {:kino_bumblebee, "~> 0.5.0"}, {:nimble_csv, "~> 1.2"} ], config: [nx: [default_backend: EXLA.Backend]] ) Kino.Frame.new(placeholder: false) ``` ## Section ```elixir html = Kino.HTML.new("""
""") main_frame = Kino.Frame.new() |> Kino.render() Kino.Frame.render(main_frame, html) Kino.Frame.new(placeholder: false) ``` ```elixir message_frame = Kino.Frame.new(placeholder: false) |> Kino.render() message_pid = spawn(fn -> receive_message = fn loop -> receive do {:message, message} -> Kino.Frame.render( message_frame, Kino.HTML.new("""
#{message}
""") ) loop.(loop) _ -> {:error} end end receive_message.(receive_message) end) Kino.Frame.new(placeholder: false) ``` ```elixir status_frame = Kino.Frame.new(placeholder: false) |> Kino.render() status_pid = spawn(fn -> receive_messages = fn loop -> receive do {:status, status} -> Kino.Frame.render( status_frame, Kino.HTML.new("""
Status: #{status}
""") ) loop.(loop) _ -> {:error} end end receive_messages.(receive_messages) end) Kino.Frame.new(placeholder: false) ``` ```elixir file_name = "messages.term" case File.exists?(file_name) do false -> File.touch!(file_name) _ -> :ok end binary = File.read!(file_name) extract_today = fn binary -> case byte_size(binary) do 0 -> [result | _] = :erlang.binary_to_term(binary) case result.date == Date.utc_today() do true -> {:ok, result.data} _ -> {:no, false} end _ -> {:no, false} end end loaded_today_data = case String.length(binary) == 0 do true -> {:no, false} _ -> extract_today.(binary) end frame = Kino.Frame.new(placeholder: false) ``` ```elixir bumblebee = fn -> {:ok, cosmo} = Bumblebee.load_model({:hf, "HuggingFaceTB/cosmo-1b"}) {:ok, tokenizer} = Bumblebee.load_tokenizer({:hf, "HuggingFaceTB/cosmo-1b"}) {:ok, generation_config} = Bumblebee.load_generation_config({:hf, "HuggingFaceTB/cosmo-1b"}) generation_config = Bumblebee.configure(generation_config, max_new_tokens: 50, strategy: %{type: :multinomial_sampling, top_p: 0.6} ) serving = Bumblebee.Text.generation(cosmo, tokenizer, generation_config, compile: [batch_size: 1, sequence_length: 256], stream: true, defn_options: [compiler: EXLA] ) Kino.start_child!({Nx.Serving, name: :cosmo, serving: serving}) %{name: :cosmo, serving: serving} end crypticize = fn subject, i -> prompt = " [INST]You will write a cryptic message in the form of a haiku in paragraph form about this headline: \"#{subject}\"[/INST]" tokens = Nx.Serving.batched_run(:cosmo, prompt) |> Stream.chunk_every(2) |> Enum.reduce([], fn token, acc -> acc ++ token end) send(status_pid, {:status, i}) tokens |> Enum.join() end Kino.Frame.new(placeholder: false) ``` ```elixir themes = [ "business", "technology", "science", "health", "politics", "world", "education", "entertainment", "games", "movie", "TV", "lifestyle", "opinion", "self-improvement", "positivism", "fun%20facts", "community", "wholesome", "human%20interest", "inspirational" ] theme = themes |> Enum.random() select_message = fn messages -> sanitize = fn text -> text |> String.replace(~r/\[\/INST\]/, "") |> String.replace(~r/\[INST\]/, "") end messages |> Enum.random() |> sanitize.() end news_loader = fn -> response = receive do {:fetched, data} -> data _ -> raise "Could not fetch data" end bumblebee.() results = response.body["results"] messages = results |> Enum.map(fn news_item -> news_item["title"] end) |> Enum.with_index() |> Enum.map(fn {subject, index} -> crypticize.(subject, index) end) date = Date.utc_today() data = messages |> Enum.join("{nextItem}") map = %{date: date, data: data, theme: theme} prev_data = case String.length(binary) == 0 do true -> [] _ -> :erlang.binary_to_term(binary) end [map] ++ prev_data end handler_pid = case loaded_today_data do {:no, _} -> spawn(fn -> receive do {:fetched, data} -> File.write(file_name, :erlang.term_to_binary(data)) _ -> raise "Could not analyze data" end end) _ -> false end loader_pid = case loaded_today_data do {:no, _} -> spawn(fn -> data = news_loader.() if is_pid(handler_pid) do send(handler_pid, {:fetched, data}) end [first_data | _] = data messages = first_data.data |> String.split("{nextItem}") Process.send_after(message_pid, {:message, select_message.(messages)}, 500) end) _ -> false end fetcher_pid = case loaded_today_data do {:no, _} -> spawn(fn -> apikey = System.fetch_env!("LB_NEWSDATA_KEY") data = Req.get!("https://newsdata.io/api/1/news?apikey=#{apikey}&q=#{theme}") if is_pid(loader_pid) do send(loader_pid, {:fetched, data}) end end) _ -> false end get_first = fn binary -> case byte_size(binary) do 0 -> false _ -> [head | _tail] = :erlang.binary_to_term(binary) head end end unpack_data = fn data -> {:ok, unpacked} = data unpacked end today_data = case loaded_today_data do {:no, _} -> case byte_size(binary) do 0 -> "" _ -> first = get_first.(binary) first.data end _ -> unpack_data.(loaded_today_data) end Kino.Frame.new(placeholder: false) ``` ```elixir random_message = today_data |> String.split("{nextItem}") |> select_message.() send(message_pid, {:message, random_message}) Kino.Frame.new(placeholder: false) ```