Packages

fnord

0.4.21

AI code archaeology

Current section

Files

Jump to
fnord lib ai tools search.ex
Raw

lib/ai/tools/search.ex

defmodule AI.Tools.Search do
require Logger
@max_search_results 5
@behaviour AI.Tools
@impl AI.Tools
def spec() do
%{
type: "function",
function: %{
name: "search_tool",
description: "searches for matching files and their contents",
parameters: %{
type: "object",
required: ["query"],
properties: %{
query: %{
type: "string",
description: "The search query string."
}
}
}
}
}
end
@impl AI.Tools
def call(agent, args) do
with {:ok, query} <- Map.fetch(args, "query") do
Logger.info("[search] searching: #{query}")
with {:ok, matches} <- search(query, agent.opts) do
files =
matches
|> Enum.map(fn {file, score, _} -> " - #{file} (#{score})" end)
|> Enum.join("\n")
Logger.debug("[search] found:\n#{files}")
matches
|> Enum.map(fn {file, score, data} ->
"""
# `#{file}` (cosine similarity: #{score})
#{data["summary"]}
"""
end)
|> Enum.join("\n-----\n")
|> then(fn res -> {:ok, "[search_tool]\n#{res}"} end)
end
end
end
# -----------------------------------------------------------------------------
# Searches the database for matches to the search query. Returns a list of
# `{file, score, data}` tuples.
# -----------------------------------------------------------------------------
defp search(query, opts) do
opts
|> Map.put(:concurrency, opts.concurrency)
|> Map.put(:detail, true)
|> Map.put(:limit, @max_search_results)
|> Map.put(:query, query)
|> Search.new()
|> Search.get_results()
|> then(&{:ok, &1})
end
end