defmodule AI.Tools.File.Notes do @behaviour AI.Tools @impl AI.Tools def async?, do: true @impl AI.Tools def is_available?, do: AI.Tools.has_indexed_project() @impl AI.Tools def ui_note_on_request(_args), do: nil @impl AI.Tools def ui_note_on_result(_args, _result), do: nil @impl AI.Tools def tool_call_failure_message(_args, _reason), do: :default @impl AI.Tools def read_args(%{"file" => file}), do: {:ok, %{"file" => file}} def read_args(%{"file_path" => file}), do: {:ok, %{"file" => file}} def read_args(_args), do: AI.Tools.required_arg_error("file") @impl AI.Tools def spec() do %{ type: "function", function: %{ name: "file_notes_tool", description: """ Returns a summary and outline of the specified file. This is information that is automatically generated by `fnord` while indexing files for semantic search. This is often MUCH more useful than the raw file contents, especially if the file may be large and you need only a high-level understanding of the file's purpose, behaviour, and linkage to other files. Use this before using the file_contents_tool to avoid pulling in unnecessary content into your context window. """, strict: true, parameters: %{ additionalProperties: false, type: "object", required: ["file"], properties: %{ file: %{ type: "string", description: """ The absolute file path to the code file in the project. This parameter must be an *indexed file* in the repository, as returned by the file_list_tool or the file_search_tool. """ } } } } } end @impl AI.Tools def call(args) do with {:ok, file} <- Map.fetch(args, "file"), {:ok, project} <- Store.get_project() do with {:ok, entry} <- AI.Tools.get_entry(file), {:ok, summary} <- Store.Project.Entry.read_summary(entry), {:ok, outline} <- Store.Project.Entry.read_outline(entry) do {:ok, format_notes(summary, outline)} else {:error, :project_not_found} -> {:error, "This project has not yet been indexed by the user."} {:error, :enoent} -> case Util.find_file_within_root(file, project.source_root) do {:ok, _} -> {:error, """ The file you requested exists but has not yet been indexed by fnord. As a result, there are no notes available for this file. Use the `file_reindex_tool` to index this file if you would like to generate notes for it. Alternatively, you can use the `file_info_tool` to retrieve specialized information about this file directly. """} _ -> {:error, """ File path not found. Please verify the correct path. """} end {:error, reason} -> {:error, "Unable to load notes: #{inspect(reason)}"} end else :error -> {:error, "Missing required parameter: file."} end end # Formats summary and outline defp format_notes(summary, outline) do """ # Summary #{summary} # Outline #{outline} """ end end