Packages
portfolio_coder
0.1.0
Code Intelligence Platform built on the Portfolio RAG ecosystem. Repository analysis, semantic code search, dependency graphs, and AI-powered code understanding with multi-language support.
Current section
Files
Jump to
Current section
Files
lib/mix/tasks/code.ask.ex
defmodule Mix.Tasks.Code.Ask do
@moduledoc """
Ask questions about indexed code.
Uses RAG (Retrieval-Augmented Generation) to answer questions
about your codebase using context from indexed files.
## Usage
mix code.ask QUESTION [OPTIONS]
## Options
* `--index` - Name of the index to use (default: "default")
* `--stream` - Stream the response (default: false)
## Examples
mix code.ask "How does authentication work?"
mix code.ask "What database queries are used?" --index my_project
mix code.ask "Explain the error handling strategy" --stream
"""
use Mix.Task
@shortdoc "Ask questions about code"
@impl Mix.Task
def run(args) do
{:ok, _} = Application.ensure_all_started(:portfolio_coder)
{opts, question_parts, _} =
OptionParser.parse(args,
strict: [
index: :string,
stream: :boolean,
help: :boolean
],
aliases: [i: :index, s: :stream, h: :help]
)
if opts[:help] do
shell_info(@moduledoc)
else
question = Enum.join(question_parts, " ")
if question == "" do
shell_error("Error: Please provide a question")
exit({:shutdown, 1})
end
ask_question(question, opts)
end
end
defp ask_question(question, opts) do
shell_info("Question: #{question}\n")
ask_opts =
[]
|> maybe_add(:index_id, opts[:index])
if opts[:stream] do
stream_answer(question, ask_opts)
else
get_answer(question, ask_opts)
end
end
defp get_answer(question, opts) do
case PortfolioCoder.ask(question, opts) do
{:ok, answer} ->
shell_info("Answer:\n")
shell_info(answer)
{:error, reason} ->
shell_error("Error: #{inspect(reason)}")
exit({:shutdown, 1})
end
end
defp stream_answer(question, opts) do
shell_info("Answer:\n")
callback = fn chunk ->
IO.write(chunk)
end
case PortfolioCoder.stream_ask(question, callback, opts) do
:ok ->
IO.puts("")
{:error, reason} ->
shell_error("\nError: #{inspect(reason)}")
exit({:shutdown, 1})
end
end
defp shell_info(message), do: IO.puts(message)
defp shell_error(message), do: IO.puts(:stderr, message)
defp maybe_add(opts, _key, nil), do: opts
defp maybe_add(opts, key, value), do: Keyword.put(opts, key, value)
end