client side and server side tool calling

This commit is contained in:
2026-03-06 09:54:00 -07:00
parent 3a065871a9
commit 713b3a2ff0
3 changed files with 52 additions and 15 deletions

View File

@@ -43,6 +43,13 @@ defmodule ElixirAi.ChatRunner do
description: "read a key value pair that was previously stored with store_thing", description: "read a key value pair that was previously stored with store_thing",
function: &ElixirAi.ToolTesting.get_thing/1, function: &ElixirAi.ToolTesting.get_thing/1,
parameters: ElixirAi.ToolTesting.get_thing_params() parameters: ElixirAi.ToolTesting.get_thing_params()
),
ai_tool(
name: "set_background_color",
description:
"set the background color of the chat interface, accepts specified tailwind colors",
function: &ElixirAi.ToolTesting.set_background_color/1,
parameters: ElixirAi.ToolTesting.set_background_color_params()
) )
] ]
end end

View File

@@ -28,21 +28,41 @@ defmodule ElixirAi.ToolTesting do
} }
end end
def store_thing_definition(name) do def store_thing_params do
%{ %{
"type" => "function", "type" => "object",
"function" => %{ "properties" => %{
"name" => name, "name" => %{"type" => "string"},
"description" => "store key value pair", "value" => %{"type" => "string"}
"parameters" => %{ },
"type" => "object", "required" => ["name", "value"]
"properties" => %{ }
"name" => %{"type" => "string"}, end
"value" => %{"type" => "string"}
}, def set_background_color(%{"color" => color}) do
"required" => ["name", "value"] Phoenix.PubSub.broadcast(ElixirAi.PubSub, "ai_chat", {:set_background_color, color})
end
def set_background_color_params do
valid_tailwind_colors = [
"bg-cyan-950/30",
"bg-red-950/30",
"bg-green-950/30",
"bg-blue-950/30",
"bg-yellow-950/30",
"bg-purple-950/30",
"bg-pink-950/30"
]
%{
"type" => "object",
"properties" => %{
"color" => %{
"type" => "string",
"enum" => valid_tailwind_colors
} }
} },
"required" => ["color"]
} }
end end

View File

@@ -15,7 +15,8 @@ defmodule ElixirAiWeb.ChatLive do
socket socket
|> assign(user_input: "") |> assign(user_input: "")
|> assign(messages: conversation.messages) |> assign(messages: conversation.messages)
|> assign(streaming_response: nil)} |> assign(streaming_response: nil)
|> assign(background_color: "bg-cyan-950/30")}
end end
def render(assigns) do def render(assigns) do
@@ -24,7 +25,11 @@ defmodule ElixirAiWeb.ChatLive do
<div class="px-4 py-3 font-semibold "> <div class="px-4 py-3 font-semibold ">
Live Chat Live Chat
</div> </div>
<div id="chat-messages" phx-hook="ScrollBottom" class="flex-1 overflow-y-auto p-4 bg-cyan-950/30 rounded-lg"> <div
id="chat-messages"
phx-hook="ScrollBottom"
class={"flex-1 overflow-y-auto p-4 rounded-lg #{@background_color}"}
>
<%= if @messages == [] do %> <%= if @messages == [] do %>
<p class="text-sm text-center mt-4">No messages yet.</p> <p class="text-sm text-center mt-4">No messages yet.</p>
<% end %> <% end %>
@@ -108,6 +113,7 @@ defmodule ElixirAiWeb.ChatLive do
def handle_info({:tool_calls_finished, tool_messages}, socket) do def handle_info({:tool_calls_finished, tool_messages}, socket) do
Logger.info("Received tool_calls_finished with #{inspect(tool_messages)}") Logger.info("Received tool_calls_finished with #{inspect(tool_messages)}")
{:noreply, {:noreply,
socket socket
|> update(:messages, &(&1 ++ tool_messages)) |> update(:messages, &(&1 ++ tool_messages))
@@ -132,4 +138,8 @@ defmodule ElixirAiWeb.ChatLive do
|> update(:messages, &(&1 ++ [final_response])) |> update(:messages, &(&1 ++ [final_response]))
|> assign(streaming_response: nil)} |> assign(streaming_response: nil)}
end end
def handle_info({:set_background_color, color}, socket) do
{:noreply, assign(socket, background_color: color)}
end
end end