Current section
Files
Jump to
Current section
Files
examples/concurrency_and_collaboration.exs
#!/usr/bin/env mix run
alias Codex.Items
defmodule Examples.Concurrency do
@moduledoc false
def parallel_analysis(files) do
tasks =
Enum.map(files, fn file ->
Task.async(fn ->
{:ok, thread} = Codex.start_thread()
prompt = """
Analyze `#{file}` for potential issues based on common Elixir patterns.
Read the file contents if you need them, and keep it to 4 bullets.
"""
case Codex.Thread.run(thread, prompt, %{timeout_ms: 90_000}) do
{:ok, result} -> {file, render(result.final_response)}
{:error, reason} -> {file, "FAILED: #{inspect(reason)}"}
end
end)
end)
await_many_with_progress(tasks, timeout_ms: 180_000, tick_ms: 5_000, label: "parallel")
|> Enum.each(fn {file, response} ->
IO.puts("\n#{file}:\n#{response}")
end)
end
def map_reduce(items) do
responses =
items
|> Enum.map(fn item ->
Task.async(fn ->
{:ok, thread} = Codex.start_thread()
prompt = "Process #{item} and summarise it succinctly (1-2 sentences)."
case Codex.Thread.run(thread, prompt, %{timeout_ms: 45_000}) do
{:ok, result} -> render(result.final_response)
{:error, reason} -> "FAILED: #{inspect(reason)}"
end
end)
end)
|> await_many_with_progress(timeout_ms: 180_000, tick_ms: 5_000, label: "map-reduce")
{:ok, thread} = Codex.start_thread()
prompt = """
Summarise these analyses into a concise checklist:
#{Enum.join(responses, "\n\n---\n\n")}
"""
{:ok, result} = Codex.Thread.run(thread, prompt)
IO.puts("\nSummary:\n#{render(result.final_response)}")
end
def collaboration(file) do
{:ok, analyzer} = Codex.start_thread()
{:ok, analysis} =
Codex.Thread.run(
analyzer,
"Analyze #{file} for potential issues. Read the file contents if needed."
)
{:ok, security} = Codex.start_thread()
{:ok, security_review} =
Codex.Thread.run(
security,
"""
Review #{file} for security issues. Read the file contents if needed.
Analysis: #{render(analysis.final_response)}
"""
)
{:ok, performance} = Codex.start_thread()
{:ok, perf_review} =
Codex.Thread.run(
performance,
"""
Review #{file} for performance issues. Read the file contents if needed.
Analysis: #{render(analysis.final_response)}
"""
)
{:ok, synthesizer} = Codex.start_thread()
prompt = """
Synthesize these reviews into actionable recommendations:
Security Review:
#{render(security_review.final_response)}
Performance Review:
#{render(perf_review.final_response)}
"""
{:ok, result} = Codex.Thread.run(synthesizer, prompt)
IO.puts("\nFinal Recommendations:")
IO.puts(render(result.final_response))
end
defp render(%Items.AgentMessage{text: text}), do: text
defp render(_), do: "(no response produced)"
defp await_many_with_progress(tasks, opts) do
timeout_ms = Keyword.fetch!(opts, :timeout_ms)
tick_ms = Keyword.fetch!(opts, :tick_ms)
label = Keyword.get(opts, :label, "tasks")
start = System.monotonic_time(:millisecond)
do_await_many_with_progress(tasks, start, timeout_ms, tick_ms, label)
end
defp do_await_many_with_progress(tasks, start_ms, timeout_ms, tick_ms, label) do
remaining_ms = timeout_ms - (System.monotonic_time(:millisecond) - start_ms)
if remaining_ms <= 0 do
Enum.each(tasks, &Task.shutdown(&1, :brutal_kill))
raise "Timed out waiting for #{label} tasks (#{timeout_ms}ms)"
end
wait_ms = min(tick_ms, remaining_ms)
yielded =
tasks
|> Task.yield_many(wait_ms)
|> Enum.map(fn {task, res} ->
{task, res || Task.yield(task, 0)}
end)
if Enum.all?(yielded, fn {_task, res} -> res != nil end) do
Enum.map(yielded, fn
{_task, {:ok, value}} -> value
{_task, {:exit, reason}} -> raise "Task failed: #{inspect(reason)}"
end)
else
elapsed_s = div(System.monotonic_time(:millisecond) - start_ms, 1000)
done = Enum.count(yielded, fn {_task, res} -> res != nil end)
total = length(yielded)
IO.puts("… #{label} still running (#{elapsed_s}s) [#{done}/#{total}]")
do_await_many_with_progress(tasks, start_ms, timeout_ms, tick_ms, label)
end
end
end
case System.argv() do
["parallel" | files] when files != [] ->
Examples.Concurrency.parallel_analysis(files)
["parallel"] ->
Examples.Concurrency.parallel_analysis(["lib/codex/thread.ex", "lib/codex/exec.ex"])
["map-reduce" | items] when items != [] ->
Examples.Concurrency.map_reduce(items)
["map-reduce"] ->
Examples.Concurrency.map_reduce(["State machine module", "Telemetry events", "Docs"])
["collaborate", file] ->
Examples.Concurrency.collaboration(file)
["collaborate"] ->
Examples.Concurrency.collaboration("lib/codex/thread.ex")
["help"] ->
IO.puts("""
mix run examples/concurrency_and_collaboration.exs [command]
parallel [files...] – run analysis concurrently
map-reduce [items...] – process items concurrently then summarise the results
collaborate [file] – run the multi-agent collaboration workflow
help – show this usage
""")
_ ->
Examples.Concurrency.parallel_analysis(["lib/codex/thread.ex"])
end