From f51401239653b63b71cc673f3a4833429b73bf39 Mon Sep 17 00:00:00 2001 From: Alex Mickelson Date: Mon, 23 Mar 2026 16:57:55 -0600 Subject: [PATCH] working on colors --- assets/css/app.css | 22 +- lib/elixir_ai_web/chat/chat_message.ex | 268 ++++++------------------- 2 files changed, 71 insertions(+), 219 deletions(-) diff --git a/assets/css/app.css b/assets/css/app.css index 53d9dae..5e15d46 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -10,17 +10,17 @@ @theme { --color-brand: #fd4f00; - --color-seafoam-50: #ecfeff; - --color-seafoam-100: #cffafe; - --color-seafoam-200: #a5f3fc; - --color-seafoam-300: #67e8f9; - --color-seafoam-400: #22d3ee; - --color-seafoam-500: #06b6d4; - --color-seafoam-600: #0891b2; - --color-seafoam-700: #0e7490; - --color-seafoam-800: #155e75; - --color-seafoam-900: #164e63; - --color-seafoam-950: #083344; + --color-seafoam-50: hsl(183.16 90% 96.27%); + --color-seafoam-100: hsl(185.11 85.92% 90.39%); + --color-seafoam-200: hsl(186.21 83.55% 81.76%); + --color-seafoam-300: hsl(186.99 82.41% 69.02%); + --color-seafoam-400: hsl(187.94 75.71% 53.33%); + --color-seafoam-500: hsl(188.74 84.5% 42.75%); + --color-seafoam-600: hsl(191.65 81.4% 36.47%); + --color-seafoam-700: hsl(192.92 72.28% 30.98%); + --color-seafoam-800: hsl(194.38 59.57% 27.06%); + --color-seafoam-900: hsl(198.18 73.33% 17.65%); + --color-seafoam-950: hsl(198.26 58.97% 7.65%); } @variant phx-click-loading (&.phx-click-loading, .phx-click-loading &); diff --git a/lib/elixir_ai_web/chat/chat_message.ex b/lib/elixir_ai_web/chat/chat_message.ex index 33cf701..366243b 100644 --- a/lib/elixir_ai_web/chat/chat_message.ex +++ b/lib/elixir_ai_web/chat/chat_message.ex @@ -199,64 +199,72 @@ defmodule ElixirAiWeb.ChatMessage do """ end - # Dispatches to the appropriate tool call component based on result state. - # Four states: - # :error key present → error (runtime failure) - # :result key present → success (runtime completed) - # :index key present → pending (streaming in-progress) - # none of the above → called (DB-loaded completed call; result is a separate message) + # Dispatches to the unified tool_call_card component, determining state from the map keys: + # :error key → :error (runtime failure) + # :result key → :success (completed) + # :index key → :pending (streaming in-progress) + # none → :called (DB-loaded; result is a separate message) attr :tool_call, :map, required: true defp tool_call_item(%{tool_call: tool_call} = assigns) do - cond do - Map.has_key?(tool_call, :error) -> - assigns = - assigns - |> assign(:name, tool_call.name) - |> assign(:arguments, tool_call[:arguments]) - |> assign(:error, tool_call.error) + state = + cond do + Map.has_key?(tool_call, :error) -> :error + Map.has_key?(tool_call, :result) -> :success + Map.has_key?(tool_call, :index) -> :pending + true -> :called + end - ~H"<.error_tool_call name={@name} arguments={@arguments} error={@error} />" + assigns = + assigns + |> assign(:_state, state) + |> assign(:_name, tool_call.name) + |> assign(:_arguments, tool_call[:arguments]) + |> assign(:_result, tool_call[:result]) + |> assign(:_error, tool_call[:error]) - Map.has_key?(tool_call, :result) -> - assigns = - assigns - |> assign(:name, tool_call.name) - |> assign(:arguments, tool_call[:arguments]) - |> assign(:result, tool_call.result) - - ~H"<.success_tool_call name={@name} arguments={@arguments} result={@result} />" - - Map.has_key?(tool_call, :index) -> - assigns = - assigns - |> assign(:name, tool_call.name) - |> assign(:arguments, tool_call[:arguments]) - - ~H"<.pending_tool_call name={@name} arguments={@arguments} />" - - true -> - assigns = - assigns - |> assign(:name, tool_call.name) - |> assign(:arguments, tool_call[:arguments]) - - ~H"<.called_tool_call name={@name} arguments={@arguments} />" - end + ~H"<.tool_call_card + state={@_state} + name={@_name} + arguments={@_arguments} + result={@_result} + error={@_error} +/>" end + attr :state, :atom, required: true attr :name, :string, required: true attr :arguments, :any, default: nil + attr :result, :any, default: nil + attr :error, :string, default: nil - defp called_tool_call(assigns) do + defp tool_call_card(assigns) do assigns = assigns |> assign(:_id, "tc-#{:erlang.phash2({assigns.name, assigns.arguments})}") |> assign(:_truncated, truncate_args(assigns.arguments)) + |> assign( + :_result_str, + case assigns.result do + nil -> nil + s when is_binary(s) -> s + other -> inspect(other, pretty: true, limit: :infinity) + end + ) ~H""" -
-
+
+
<.tool_call_icon /> {@name} @@ -286,7 +294,7 @@ defmodule ElixirAiWeb.ChatMessage do /> - + called -
- -
- """ - end - - attr :name, :string, required: true - attr :arguments, :any, default: nil - - defp pending_tool_call(assigns) do - assigns = - assigns - |> assign(:_id, "tc-#{:erlang.phash2({assigns.name, assigns.arguments})}") - |> assign(:_truncated, truncate_args(assigns.arguments)) - - ~H""" -
-
- <.tool_call_icon /> - {@name} - - {@_truncated} - - - - + running -
- -
- """ - end - - attr :name, :string, required: true - attr :arguments, :any, default: nil - attr :result, :any, required: true - - defp success_tool_call(assigns) do - assigns = - assigns - |> assign( - :result_str, - case assigns.result do - s when is_binary(s) -> s - other -> inspect(other, pretty: true, limit: :infinity) - end - ) - |> assign(:_id, "tc-#{:erlang.phash2({assigns.name, assigns.arguments})}") - |> assign(:_truncated, truncate_args(assigns.arguments)) - - ~H""" -
-
- <.tool_call_icon /> - {@name} - - {@_truncated} - - - - + done -
- -
-
result
-
{@result_str}
-
-
- """ - end - - attr :name, :string, required: true - attr :arguments, :any, default: nil - attr :error, :string, required: true - - defp error_tool_call(assigns) do - assigns = - assigns - |> assign(:_id, "tc-#{:erlang.phash2({assigns.name, assigns.arguments})}") - |> assign(:_truncated, truncate_args(assigns.arguments)) - - ~H""" -
-
- <.tool_call_icon /> - {@name} - - {@_truncated} - - - - +
-
+
+
result
+
{@_result_str}
+
+
error
{@error}
@@ -542,7 +394,7 @@ defmodule ElixirAiWeb.ChatMessage do ~H"""
-
arguments
+
arguments
{@pretty_args}
"""