defmodule ExVoix.Html.Components do @moduledoc """ Provides VOIX framework components for tool and context element. """ use Phoenix.Component import Phoenix.HTML # alias Phoenix.LiveView.JS alias ExVoix.ModelContext.Registry @doc """ Renders a tool element. ## Examples <.tool mcp={@mcp} name={@name} /> """ attr :mcp, :atom, required: true, doc: "the module of mcp server" attr :name, :any, required: true, doc: "the name of tool" attr :item_id, :integer, doc: "the id related to item tool" attr :item_label, :string, doc: "the label related to item tool" def tool(assigns) do mcp = Registry.load_mcps() |> Enum.filter(fn it -> it == assigns[:mcp] end) |> Enum.at(0) assigns = if not is_nil(mcp) do tool = Registry.load_tool(mcp, assigns[:name]) |> Enum.at(0) # IO.inspect(tool, label: "tool element") assigns = assigns |> assign_new(:tool_name, fn _ -> if not is_nil(assigns[:item_id]) and not is_nil(Map.get(tool, "title")), do: EEx.eval_string(Map.get(tool, "title"), [item_id: assigns[:item_id]]), else: Map.get(tool, "name") end) |> assign_new(:tool_desc, fn _ -> if not is_nil(assigns[:item_label]), do: EEx.eval_string(Map.get(tool, "description"), [item_label: assigns[:item_label]]), else: Map.get(tool, "description") end) props = Map.get(tool, "inputSchema") |> Map.get("properties") properties = Enum.map(props, fn {prop_name, prop_info} -> "" end) assigns |> assign_new(:props, fn _ -> properties end) else assigns end ~H""" """ end @doc """ Renders a context element. ## Examples <.context name={@name} content={@content} /> """ attr :name, :string, required: true, doc: "the name of context" attr :content, :string, required: true, doc: "the content of context" def context(assigns) do ~H""" @name} name={@name} class="hidden"> {raw(@content)} """ end end