Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Function calling with ollama

livebooks/function_calling_ollama.livemd

Function calling with ollama

Mix.install([
  :req,
  :jason
])

Module to calculate the distance between to cities in km

defmodule Geo do
  @earth_radius 6371

  def haversine(lat1, lon1, lat2, lon2) do
    dlat = radians(lat2 - lat1)
    dlon = radians(lon2 - lon1)

    a =
      :math.pow(:math.sin(dlat / 2), 2) +
        :math.cos(radians(lat1)) * :math.cos(radians(lat2)) *
          :math.pow(:math.sin(dlon / 2), 2)

    c = 2 * :math.atan2(:math.sqrt(a), :math.sqrt(1 - a))

    @earth_radius * c
  end

  defp radians(degrees) do
    degrees * :math.pi() / 180
  end
end

# London to New York
distance = Geo.haversine(51.5074, 0.1278, 40.7128, -74.0060)
IO.puts("The distance is: #{distance} km")

Find the distance between two cities

defmodule GeoCoordinates do
  @url "http://localhost:11434/api/chat"
  @model "adrienbrault/nous-hermes2pro:Q5_K_S"

  def get_city_coordinates(city) do
    schema =
      %{
        "city" => %{
          "type" => "string",
          "description" => "Name of the city"
        },
        "country" => %{
          "type" => "string",
          "description" => "Name of the country in which the city is it"
        },
        "lat" => %{
          "type" => "float",
          "description" => "Decimal latitude of the city"
        },
        "lon" => %{
          "type" => "float",
          "description" => "Decimal longitude of the city"
        }
      }
      |> Jason.encode!()

    payload = %{
      "model" => @model,
      "messages" => [
        %{
          "role" => "system",
          "content" =>
            "You are helpful AI assistant. The user will enter city name and the assistant will return decimal latitude and decimal longitute of the city.\nRespond using JSON in the schema defined here:\n#{schema}."
        },
        %{"role" => "user", "content" => "#{city}"}
      ],
      "stream" => false,
      "format" => "json"
    }

    resp = Req.post!(@url, json: payload, receive_timeout: 60_000)
    (resp.body["message"]["content"] || "{}") |> Jason.decode!()
  end
end

city1 = GeoCoordinates.get_city_coordinates("Plovdiv, Bulgaria")
city2 = GeoCoordinates.get_city_coordinates("Witham, England")
distance_km = Geo.haversine(city1["lat"], city1["lon"], city2["lat"], city2["lon"])

if city1["country"] == city2["country"] do
  "The distance between #{city1["city"]} and #{city2["city"]} is #{:erlang.float_to_binary(distance_km, decimals: 2)}km"
else
  "The distance between #{city1["city"]}, #{city1["country"]} and #{city2["city"]}, #{city2["country"]} is #{:erlang.float_to_binary(distance_km, decimals: 2)}km"
end