/ apps / echo_shared / scripts / add_llm_to_agent.sh
add_llm_to_agent.sh
  1  #!/bin/bash
  2  
  3  # Script to add LLM integration to an ECHO agent
  4  # Usage: ./add_llm_to_agent.sh <agent_name> <agent_role>
  5  # Example: ./add_llm_to_agent.sh chro chro
  6  
  7  set -e
  8  
  9  if [ "$#" -ne 2 ]; then
 10      echo "Usage: $0 <agent_name> <agent_role>"
 11      echo "Example: $0 chro chro"
 12      exit 1
 13  fi
 14  
 15  AGENT_NAME=$1
 16  AGENT_ROLE=$2
 17  AGENT_DIR="../agents/${AGENT_NAME}"
 18  AGENT_FILE="${AGENT_DIR}/lib/${AGENT_NAME}.ex"
 19  
 20  if [ ! -f "$AGENT_FILE" ]; then
 21      echo "Error: Agent file not found: $AGENT_FILE"
 22      exit 1
 23  fi
 24  
 25  echo "Adding LLM integration to ${AGENT_NAME} agent..."
 26  
 27  # Create backup
 28  cp "$AGENT_FILE" "${AGENT_FILE}.backup"
 29  
 30  # The integration will be done manually via Elixir since shell scripting for complex edits is error-prone
 31  # Instead, we'll create an Elixir script to do the modifications
 32  
 33  cat > /tmp/add_llm_integration.exs << 'EOF'
 34  [agent_file, agent_role] = System.argv()
 35  
 36  content = File.read!(agent_file)
 37  
 38  # Step 1: Add DecisionHelper alias after Repo alias
 39  if String.contains?(content, "alias EchoShared.LLM.DecisionHelper") do
 40    IO.puts("✓ DecisionHelper alias already present")
 41  else
 42    content = String.replace(
 43      content,
 44      ~r/(alias EchoShared\.Repo)/,
 45      "\\1\n  alias EchoShared.LLM.DecisionHelper"
 46    )
 47    IO.puts("✓ Added DecisionHelper alias")
 48  end
 49  
 50  # Step 2: Add ai_consult tool before closing the tools list
 51  if String.contains?(content, ~s("ai_consult")) do
 52    IO.puts("✓ ai_consult tool already present")
 53  else
 54    # Find the last tool in the array and add ai_consult after it
 55    ai_consult_tool = """
 56        },
 57        %{
 58          name: "ai_consult",
 59          description: "Consult AI advisor for insights and analysis",
 60          inputSchema: %{
 61            type: "object",
 62            properties: %{
 63              query_type: %{
 64                type: "string",
 65                enum: ["decision_analysis", "question", "option_evaluation"],
 66                description: "Type of AI consultation"
 67              },
 68              question: %{
 69                type: "string",
 70                description: "The question or decision to analyze"
 71              },
 72              context: %{
 73                type: "object",
 74                description: "Additional context"
 75              }
 76            },
 77            required: ["query_type", "question"]
 78          }
 79        }
 80      ]
 81    end
 82    """
 83  
 84    content = String.replace(
 85      content,
 86      ~r/\}\n    \]\n  end\n\n  @impl true\n  def execute_tool/,
 87      ai_consult_tool <> "\n\n  @impl true\n  def execute_tool"
 88    )
 89    IO.puts("✓ Added ai_consult tool")
 90  end
 91  
 92  # Step 3: Add execute_tool for ai_consult
 93  if String.contains?(content, ~s(def execute_tool("ai_consult")) do
 94    IO.puts("✓ ai_consult execute_tool already present")
 95  else
 96    ai_consult_impl = """
 97  
 98    def execute_tool("ai_consult", args) do
 99      with {:ok, query_type} <- validate_required_string(args, "query_type"),
100           {:ok, question} <- validate_required_string(args, "question") do
101  
102        context = args["context"] || %{}
103  
104        result = case query_type do
105          "decision_analysis" ->
106            decision_context = Map.merge(context, %{
107              decision_type: context["decision_type"] || "general",
108              context: question
109            })
110            DecisionHelper.analyze_decision(:#{agent_role}, decision_context)
111  
112          "option_evaluation" ->
113            evaluation_context = %{
114              question: question,
115              options: context["options"] || [],
116              criteria: context["criteria"]
117            }
118            DecisionHelper.evaluate_options(:#{agent_role}, evaluation_context)
119  
120          "question" ->
121            DecisionHelper.consult(:#{agent_role}, question, context["additional_context"])
122  
123          _ ->
124            {:error, "Unknown query type: #{query_type}"}
125        end
126  
127        case result do
128          {:ok, response} ->
129            {:ok, "AI Consultation Result:\\n\\n" <> response <> "\\n\\n---\\nNote: AI-generated advice."}
130          {:error, :llm_disabled} ->
131            {:ok, "AI consultation is currently disabled. Enable with #{String.upcase(agent_role)}_LLM_ENABLED=true"}
132          {:error, reason} ->
133            {:error, "AI consultation failed: #{inspect(reason)}"}
134        end
135      end
136    end
137    """
138  
139    content = String.replace(
140      content,
141      ~r/\n  def execute_tool\(name, _args\) do\n    \{:error, "Unknown tool: #\{name\}"\}\n  end/,
142      ai_consult_impl <> "\n\n  def execute_tool(name, _args) do\n    {:error, \"Unknown tool: \#{name}\"}\n  end"
143    )
144    IO.puts("✓ Added ai_consult execute_tool implementation")
145  end
146  
147  # Step 4: Add LLM helper functions before final end
148  if String.contains?(content, "## LLM Consultation Helpers") do
149    IO.puts("✓ LLM helper functions already present")
150  else
151    llm_helpers = """
152  
153    ## LLM Consultation Helpers
154  
155    defp consult_llm_for_decision(decision_context) do
156      DecisionHelper.analyze_decision(:#{agent_role}, decision_context)
157    end
158  
159    defp consult_llm_for_evaluation(evaluation_context) do
160      DecisionHelper.evaluate_options(:#{agent_role}, evaluation_context)
161    end
162  
163    defp consult_llm_simple(question, context) do
164      DecisionHelper.consult(:#{agent_role}, question, context)
165    end
166  """
167  
168    content = String.replace(
169      content,
170      ~r/end\n$/,
171      llm_helpers <> "end\n"
172    )
173    IO.puts("✓ Added LLM helper functions")
174  end
175  
176  File.write!(agent_file, content)
177  IO.puts("✅ Successfully integrated LLM into #{agent_role} agent!")
178  EOF
179  
180  # Run the Elixir script
181  elixir /tmp/add_llm_integration.exs "$AGENT_FILE" "$AGENT_ROLE"
182  
183  echo "Done! Backup created at ${AGENT_FILE}.backup"