Current section

Files

Jump to
codex_sdk examples file_search_tool.exs
Raw

examples/file_search_tool.exs

# Example: FileSearch Tool Usage
# Run: mix run examples/file_search_tool.exs
#
# This example demonstrates using the FileSearchTool to search for files
# by glob patterns and optionally filter by content.
Mix.Task.run("app.start")
alias Codex.Tools
alias Codex.Tools.FileSearchTool
IO.puts("""
=== FileSearch Tool Example ===
This example demonstrates the FileSearch hosted tool for searching
local files by glob patterns and content matching.
""")
# Reset and register the file search tool
Tools.reset!()
{:ok, _} = Tools.register(FileSearchTool)
IO.puts("Registered FileSearchTool\n")
# Example 1: Find all Elixir files in lib/
IO.puts("--- Example 1: Find all Elixir files in lib/ ---")
{:ok, result} = Tools.invoke("file_search", %{"pattern" => "lib/**/*.ex"}, %{})
IO.puts("Found #{result["count"]} Elixir files in lib/")
if result["count"] > 0 do
IO.puts("First 5 files:")
result["files"]
|> Enum.take(5)
|> Enum.each(fn file ->
IO.puts(" - #{file["path"]}")
end)
end
IO.puts("")
# Example 2: Find files with specific content
IO.puts("--- Example 2: Search for files containing 'defmodule' ---")
{:ok, result} =
Tools.invoke(
"file_search",
%{"pattern" => "lib/**/*.ex", "content" => "defmodule", "max_results" => 10},
%{}
)
IO.puts("Found #{result["count"]} files containing 'defmodule'")
if result["count"] > 0 do
IO.puts("\nFiles with matches:")
for file <- Enum.take(result["files"], 5) do
match_count = length(file["matches"])
IO.puts(" #{file["path"]} (#{match_count} match#{if match_count > 1, do: "es", else: ""})")
for match <- Enum.take(file["matches"], 2) do
IO.puts(" Line #{match["line"]}: #{String.slice(match["text"], 0, 60)}...")
end
end
end
IO.puts("")
# Example 3: Case-insensitive search
IO.puts("--- Example 3: Case-insensitive search ---")
{:ok, result} =
Tools.invoke(
"file_search",
%{
"pattern" => "lib/**/*.ex",
"content" => "ERROR",
"case_sensitive" => false,
"max_results" => 5
},
%{}
)
IO.puts("Found #{result["count"]} files containing 'error' (case-insensitive)")
if result["count"] > 0 do
for file <- result["files"] do
IO.puts(" #{file["path"]}")
end
end
IO.puts("")
# Example 4: Find test files
IO.puts("--- Example 4: Find test files ---")
{:ok, result} = Tools.invoke("file_search", %{"pattern" => "test/**/*_test.exs"}, %{})
IO.puts("Found #{result["count"]} test files")
if result["count"] > 0 do
IO.puts("First 5 test files:")
result["files"]
|> Enum.take(5)
|> Enum.each(fn file ->
IO.puts(" - #{file["path"]}")
end)
end
IO.puts("")
# Example 5: Multiple extensions
IO.puts("--- Example 5: Find Elixir source and script files ---")
{:ok, result} = Tools.invoke("file_search", %{"pattern" => "lib/**/*.{ex,exs}"}, %{})
IO.puts("Found #{result["count"]} .ex and .exs files in lib/")
IO.puts("")
# Example 6: Using with custom base_path
IO.puts("--- Example 6: Search in specific directory ---")
{:ok, result} =
Tools.invoke("file_search", %{"pattern" => "*.ex", "base_path" => "lib/codex"}, %{})
IO.puts("Found #{result["count"]} .ex files directly in lib/codex/")
if result["count"] > 0 do
for file <- Enum.take(result["files"], 5) do
IO.puts(" - #{file["path"]}")
end
end
IO.puts("")
# Example 7: Search with fixed content
IO.puts("--- Example 7: Fixed content search ---")
{:ok, result} =
Tools.invoke(
"file_search",
%{
"pattern" => "lib/**/*.ex",
"content" => "def ",
"max_results" => 5
},
%{}
)
IO.puts("Found #{result["count"]} files with function definitions")
if result["count"] > 0 do
file = hd(result["files"])
IO.puts("Sample from #{file["path"]}:")
for match <- Enum.take(file["matches"], 3) do
IO.puts(" Line #{match["line"]}: #{match["text"]}")
end
end
IO.puts("\n=== Example Complete ===")