defmodule SuperintelligenceWeb.ChatController do use SuperintelligenceWeb, :controller alias Superintelligence.Conversations alias Superintelligence.AIAgent @doc """ List all conversations """ def index(conn, _params) do conversations = Conversations.list_conversations() json(conn, %{conversations: conversations}) end @doc """ Get a specific conversation with messages """ def show(conn, %{"id" => id}) do case Conversations.get_conversation(id) do {:ok, conversation} -> messages = Conversations.list_messages(id) json(conn, %{ conversation: conversation, messages: messages }) {:error, :not_found} -> conn |> put_status(:not_found) |> json(%{error: "Conversation not found"}) end end @doc """ Create a new conversation """ def create(conn, %{"title" => title}) do case Conversations.create_conversation(%{title: title}) do {:ok, conversation} -> conn |> put_status(:created) |> json(%{conversation: conversation}) {:error, reason} -> conn |> put_status(:unprocessable_entity) |> json(%{error: reason}) end end @doc """ Send a message in a conversation """ def send_message(conn, %{"conversation_id" => conversation_id, "message" => message_params}) do with {:ok, _conversation} <- Conversations.get_conversation(conversation_id), {:ok, user_message} <- Conversations.create_message(conversation_id, %{ role: "user", content: message_params["content"] }) do # Process with AI agent asynchronously Task.start(fn -> process_ai_response(conversation_id, message_params["content"]) end) json(conn, %{message: user_message}) else {:error, :not_found} -> conn |> put_status(:not_found) |> json(%{error: "Conversation not found"}) {:error, reason} -> conn |> put_status(:unprocessable_entity) |> json(%{error: reason}) end end @doc """ Generate a visualization """ def generate_visualization(conn, %{"type" => type, "data" => data}) do visualization = case type do "chart" -> %{ type: "chart", data: %{ type: data["chart_type"] || "bar", labels: data["labels"] || ["A", "B", "C", "D", "E"], values: data["values"] || Enum.map(1..5, fn _ -> :rand.uniform(100) end) } } "graph" -> %{ type: "graph", data: %{ nodes: data["nodes"] || generate_sample_nodes(), edges: data["edges"] || generate_sample_edges() } } "custom" -> %{ type: "custom", data: %{ commands: data["commands"] || [] } } _ -> %{type: "unknown", data: %{}} end json(conn, %{visualization: visualization}) end defp process_ai_response(conversation_id, user_message) do # Here you would integrate with your AI agent # For now, we'll use a simple mock response Process.sleep(1000) # Simulate processing time response = generate_ai_response(user_message) Conversations.create_message(conversation_id, %{ role: "assistant", content: response.content, metadata: response.metadata }) end defp generate_ai_response(message) do cond do String.contains?(String.downcase(message), ["chart", "graph", "visualiz"]) -> %{ content: "I'll create a visualization for you. Here's a chart showing your data:", metadata: %{ visualization: %{ type: "chart", data: %{ type: "bar", labels: ["Q1", "Q2", "Q3", "Q4"], values: Enum.map(1..4, fn _ -> :rand.uniform(100) end) } } } } String.contains?(String.downcase(message), "hello") -> %{ content: "Hello! I'm your AI assistant. How can I help you today?", metadata: %{} } true -> %{ content: "I understand. Let me help you with that. What specific information do you need?", metadata: %{} } end end defp generate_sample_nodes do Enum.map(1..5, fn i -> %{ id: "node#{i}", label: "Node #{i}", x: :rand.uniform(300), y: :rand.uniform(300) } end) end defp generate_sample_edges do [ %{source: "node1", target: "node2"}, %{source: "node2", target: "node3"}, %{source: "node3", target: "node4"}, %{source: "node4", target: "node5"}, %{source: "node5", target: "node1"} ] end end