Packages

A Fair Source multi-agent runtime with deterministic agent scoring and replayable run history.

Current section

Files

Jump to
syntropy lib syntropy_web controllers api controller_helpers.ex
Raw

lib/syntropy_web/controllers/api/controller_helpers.ex

defmodule SyntropyWeb.Api.ControllerHelpers do
@moduledoc false
import Phoenix.Controller, only: [json: 2]
import Plug.Conn, only: [put_status: 2]
@max_limit 100
@spec limit(map(), non_neg_integer()) :: non_neg_integer()
def limit(params, default \\ @max_limit) do
case Map.get(params, "limit") do
nil ->
default
limit when is_integer(limit) ->
normalize_limit(limit, default)
limit when is_binary(limit) ->
case Integer.parse(limit) do
{parsed, ""} -> normalize_limit(parsed, default)
_other -> default
end
_other ->
default
end
end
@spec not_found(Plug.Conn.t(), String.t(), String.t()) :: Plug.Conn.t()
def not_found(conn, resource, id) do
error(conn, :not_found, "not_found", "#{resource} #{id} was not found.")
end
@spec invalid_request(Plug.Conn.t(), String.t(), list(map())) :: Plug.Conn.t()
def invalid_request(conn, message, details) do
error(conn, :unprocessable_entity, "invalid_request", message, details)
end
@spec conflict(Plug.Conn.t(), String.t(), String.t()) :: Plug.Conn.t()
def conflict(conn, code, message) do
error(conn, :conflict, code, message)
end
@spec task_failure(Plug.Conn.t(), term()) :: Plug.Conn.t()
def task_failure(conn, reason) do
case reason do
:no_agents ->
error(conn, :unprocessable_entity, "task_rejected", "No agents were available.")
:no_successful_thoughts ->
error(conn, :unprocessable_entity, "task_rejected", "No agents completed the task.")
:quota_exceeded ->
error(
conn,
:too_many_requests,
"quota_exceeded",
"The fair-use token budget for the rolling 30-day window is exhausted."
)
_other ->
error(conn, :internal_server_error, "task_failed", "Task execution failed.")
end
end
defp error(conn, status, code, message, details \\ nil) do
body =
%{
error: %{
code: code,
message: message
}
}
|> maybe_put_details(details)
conn
|> put_status(status)
|> json(body)
end
defp maybe_put_details(body, nil), do: body
defp maybe_put_details(body, details), do: put_in(body, [:error, :details], details)
defp normalize_limit(limit, _default) when is_integer(limit) and limit > 0 do
min(limit, @max_limit)
end
defp normalize_limit(_limit, default), do: default
end