Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions lib/console/ai/graph/provider/elastic.ex
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ defmodule Console.AI.Graph.Provider.Elastic do

def init(%__MODULE__{conn: %Elastic{index: index} = es}) do
Elastic.url(es, curr_index(index))
|> HTTPoison.put(Jason.encode!(@index_mappings), Elastic.headers(es, @headers))
|> Req.put(headers: Elastic.headers(es, @headers), body: Jason.encode!(@index_mappings), decode_body: false, retry: false)
|> handle_response("could not initialize elasticsearch:")
end

Expand All @@ -56,7 +56,7 @@ defmodule Console.AI.Graph.Provider.Elastic do
|> Enum.join("\n")

Elastic.url(es, "/_bulk")
|> HTTPoison.post("#{bulk}\n", Elastic.headers(es, [{"Content-Type", "application/x-ndjson"}]))
|> Req.post(headers: Elastic.headers(es, [{"Content-Type", "application/x-ndjson"}]), body: "#{bulk}\n", decode_body: false, retry: false)
|> handle_response("could not bulk index into elasticsearch:")
end

Expand Down Expand Up @@ -133,8 +133,8 @@ defmodule Console.AI.Graph.Provider.Elastic do
defp groups(%User{group_members: [_ | _] = members}), do: [%{terms: %{group_ids: Enum.map(members, & &1.group_id)}}]
defp groups(_), do: []

defp handle_response({:ok, %HTTPoison.Response{status_code: code}}, _) when code >= 200 and code < 300, do: :ok
defp handle_response({:ok, %HTTPoison.Response{body: body}}, modifier), do: {:error, "#{modifier}: #{body}"}
defp handle_response({:ok, %Req.Response{status: code}}, _) when code >= 200 and code < 300, do: :ok
defp handle_response({:ok, %Req.Response{body: body}}, modifier), do: {:error, "#{modifier}: #{body}"}
defp handle_response(_, modifier), do: {:error, "#{modifier}: elasticsearch error"}

def curr_index(index) when is_binary(index) do
Expand Down
8 changes: 4 additions & 4 deletions lib/console/ai/provider/ollama.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ defmodule Console.AI.Ollama do

@base_headers [{"content-type", "application/json"}]

@options [recv_timeout: :timer.minutes(5), timeout: :timer.minutes(5)]
@options [receive_timeout: :timer.minutes(5), connect_options: [timeout: :timer.minutes(5)], decode_body: false, retry: false]

defmodule Message do
@type t :: %__MODULE__{}
Expand Down Expand Up @@ -77,13 +77,13 @@ defmodule Console.AI.Ollama do
})

"#{url}/api/chat"
|> HTTPoison.post(body, auth(ollama, @base_headers), @options)
|> Req.post([headers: auth(ollama, @base_headers), body: body] ++ @options)
|> handle_response(ChatResponse.spec())
end

defp handle_response({:ok, %HTTPoison.Response{status_code: code, body: body}}, type) when code in 200..299,
defp handle_response({:ok, %Req.Response{status: code, body: body}}, type) when code in 200..299,
do: Poison.decode(body, as: type)
defp handle_response({:ok, %HTTPoison.Response{body: body}}, _) do
defp handle_response({:ok, %Req.Response{body: body}}, _) do
Logger.error "ollama error: #{body}"
{:error, "ollama error: #{body}"}
end
Expand Down
15 changes: 12 additions & 3 deletions lib/console/ai/tools/workbench/http.ex
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,25 @@ defmodule Console.AI.Tools.Workbench.Http do

def invoke(%WorkbenchTool{configuration: %Configuration{http: http}}, %{} = input) do
with {:body, {:ok, body}} <- {:body, body(http, input)},
{:request, {:ok, %HTTPoison.Response{body: body, status_code: code}}} <- {:request, do_request(http, body)} do
{:request, {:ok, %Req.Response{body: body, status: code}}} <- {:request, do_request(http, body)} do
{:ok, "http response: #{body} (status #{code})"}
else
{:body, {:error, error}} -> {:error, "could not render request body: #{inspect(error)}"}
{:request, {:error, %HTTPoison.Error{reason: reason}}} -> {:error, "HTTP error: #{inspect(reason)}"}
{:request, {:error, reason}} -> {:error, "HTTP error: #{inspect(reason)}"}
end
end

defp do_request(%HttpConfiguration{method: method, url: url} = config, body) do
HTTPoison.request(method, url, body, headers(config), [timeout: 10_000, recv_timeout: 10_000])
Req.request(
method: method,
url: url,
body: body,
headers: headers(config),
connect_options: [timeout: 10_000],
receive_timeout: 10_000,
decode_body: false,
retry: false
)
end

defp headers(%HttpConfiguration{headers: [_ | _] = headers}), do: Enum.map(headers, &{&1.name, &1.value})
Expand Down
26 changes: 13 additions & 13 deletions lib/console/ai/tools/workbench/integration/azure_devops/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,11 @@ defmodule Console.AI.Tools.Workbench.Integration.AzureDevops.Client do
def get_json(%{token: _} = client, url, query \\ %{}) when is_binary(url) do
req_url = url <> Query.query_string(query)

case HTTPoison.get(req_url, basic_auth_header(client), http_opts()) do
{:ok, %HTTPoison.Response{status_code: code, body: body}} when code >= 200 and code < 300 ->
case Req.get(req_url, [headers: basic_auth_header(client)] ++ http_opts()) do
{:ok, %Req.Response{status: code, body: body}} when code >= 200 and code < 300 ->
decode_json(body)

{:ok, %HTTPoison.Response{status_code: code, body: body}} ->
{:ok, %Req.Response{status: code, body: body}} ->
{:error, "Azure DevOps API #{code}: #{inspect(body)}"}

{:error, reason} ->
Expand All @@ -132,11 +132,11 @@ defmodule Console.AI.Tools.Workbench.Integration.AzureDevops.Client do
encoded = Jason.encode!(body_map)
headers = json_auth_headers(client)

case HTTPoison.post(url, encoded, headers, http_opts()) do
{:ok, %HTTPoison.Response{status_code: code, body: body}} when code >= 200 and code < 300 ->
case Req.post(url, [headers: headers, body: encoded] ++ http_opts()) do
{:ok, %Req.Response{status: code, body: body}} when code >= 200 and code < 300 ->
decode_json(body)

{:ok, %HTTPoison.Response{status_code: code, body: body}} ->
{:ok, %Req.Response{status: code, body: body}} ->
{:error, "Azure DevOps API #{code}: #{inspect(body)}"}

{:error, reason} ->
Expand All @@ -153,11 +153,11 @@ defmodule Console.AI.Tools.Workbench.Integration.AzureDevops.Client do
{Jason.encode!(body_map), json_auth_headers(client)}
end

case HTTPoison.put(url, encoded, headers, http_opts()) do
{:ok, %HTTPoison.Response{status_code: code, body: body}} when code >= 200 and code < 300 ->
case Req.put(url, [headers: headers, body: encoded] ++ http_opts()) do
{:ok, %Req.Response{status: code, body: body}} when code >= 200 and code < 300 ->
decode_json(body)

{:ok, %HTTPoison.Response{status_code: code, body: body}} ->
{:ok, %Req.Response{status: code, body: body}} ->
{:error, "Azure DevOps API #{code}: #{inspect(body)}"}

{:error, reason} ->
Expand All @@ -167,11 +167,11 @@ defmodule Console.AI.Tools.Workbench.Integration.AzureDevops.Client do

@spec post_empty(map(), String.t()) :: {:ok, term()} | {:error, String.t()}
def post_empty(%{token: _} = client, url) when is_binary(url) do
case HTTPoison.post(url, "", basic_auth_header(client), http_opts()) do
{:ok, %HTTPoison.Response{status_code: code, body: body}} when code >= 200 and code < 300 ->
case Req.post(url, [headers: basic_auth_header(client), body: ""] ++ http_opts()) do
{:ok, %Req.Response{status: code, body: body}} when code >= 200 and code < 300 ->
decode_json(body)

{:ok, %HTTPoison.Response{status_code: code, body: body}} ->
{:ok, %Req.Response{status: code, body: body}} ->
{:error, "Azure DevOps API #{code}: #{inspect(body)}"}

{:error, reason} ->
Expand All @@ -190,5 +190,5 @@ defmodule Console.AI.Tools.Workbench.Integration.AzureDevops.Client do

defp http_opts,
do:
Application.get_env(:console, :httpoison_azure_devops_options, []) ++ [recv_timeout: 60_000]
Console.Utils.HTTP.provider_options(:httpoison_azure_devops_options, :req_azure_devops_options) ++ [receive_timeout: 60_000, decode_body: false, retry: false]
end
14 changes: 7 additions & 7 deletions lib/console/ai/tools/workbench/integration/bitbucket/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ defmodule Console.AI.Tools.Workbench.Integration.Bitbucket.Client do
def get(%{base_url: base, token: token}, path, query \\ %{}) when is_binary(path) do
url = base <> path <> Query.query_string(query)

case HTTPoison.get(url, auth_headers(token), http_opts()) do
{:ok, %HTTPoison.Response{status_code: code, body: body}} when code >= 200 and code < 300 ->
case Req.get(url, [headers: auth_headers(token)] ++ http_opts()) do
{:ok, %Req.Response{status: code, body: body}} when code >= 200 and code < 300 ->
decode_json(body)

{:ok, %HTTPoison.Response{status_code: code, body: body}} ->
{:ok, %Req.Response{status: code, body: body}} ->
{:error, "Bitbucket Cloud API #{code}: #{inspect(body)}"}

{:error, reason} ->
Expand All @@ -68,11 +68,11 @@ defmodule Console.AI.Tools.Workbench.Integration.Bitbucket.Client do
url = base <> path
headers = auth_headers(token) ++ [{"Content-Type", "application/json"}]

case HTTPoison.post(url, Jason.encode!(body_map), headers, http_opts()) do
{:ok, %HTTPoison.Response{status_code: code, body: body}} when code >= 200 and code < 300 ->
case Req.post(url, [headers: headers, body: Jason.encode!(body_map)] ++ http_opts()) do
{:ok, %Req.Response{status: code, body: body}} when code >= 200 and code < 300 ->
decode_json(body)

{:ok, %HTTPoison.Response{status_code: code, body: body}} ->
{:ok, %Req.Response{status: code, body: body}} ->
{:error, "Bitbucket Cloud API #{code}: #{inspect(body)}"}

{:error, reason} ->
Expand Down Expand Up @@ -103,5 +103,5 @@ defmodule Console.AI.Tools.Workbench.Integration.Bitbucket.Client do
defp enc(s) when is_binary(s), do: URI.encode(String.trim(s), &URI.char_unreserved?/1)

defp http_opts,
do: Application.get_env(:console, :httpoison_bitbucket_options, []) ++ [recv_timeout: 60_000]
do: Console.Utils.HTTP.provider_options(:httpoison_bitbucket_options, :req_bitbucket_options) ++ [receive_timeout: 60_000, decode_body: false, retry: false]
end
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ defmodule Console.AI.Tools.Workbench.Integration.BitbucketDatacenter.Client do
def get(%{api_base: base, token: token}, path, query \\ %{}) when is_binary(path) do
url = base <> path <> Query.query_string(query)

case HTTPoison.get(url, auth_headers(token), http_opts()) do
{:ok, %HTTPoison.Response{status_code: code, body: body}} when code >= 200 and code < 300 ->
case Req.get(url, [headers: auth_headers(token)] ++ http_opts()) do
{:ok, %Req.Response{status: code, body: body}} when code >= 200 and code < 300 ->
decode_json(body)

{:ok, %HTTPoison.Response{status_code: code, body: body}} ->
{:ok, %Req.Response{status: code, body: body}} ->
{:error, "Bitbucket Data Center API #{code}: #{inspect(body)}"}

{:error, reason} ->
Expand All @@ -68,11 +68,11 @@ defmodule Console.AI.Tools.Workbench.Integration.BitbucketDatacenter.Client do
url = base <> path
headers = auth_headers(token) ++ [{"Content-Type", "application/json"}]

case HTTPoison.post(url, Jason.encode!(body_map), headers, http_opts()) do
{:ok, %HTTPoison.Response{status_code: code, body: body}} when code >= 200 and code < 300 ->
case Req.post(url, [headers: headers, body: Jason.encode!(body_map)] ++ http_opts()) do
{:ok, %Req.Response{status: code, body: body}} when code >= 200 and code < 300 ->
decode_json(body)

{:ok, %HTTPoison.Response{status_code: code, body: body}} ->
{:ok, %Req.Response{status: code, body: body}} ->
{:error, "Bitbucket Data Center API #{code}: #{inspect(body)}"}

{:error, reason} ->
Expand All @@ -84,11 +84,11 @@ defmodule Console.AI.Tools.Workbench.Integration.BitbucketDatacenter.Client do
def put_empty(%{token: token}, url) when is_binary(url) do
headers = auth_headers(token) ++ [{"Content-Type", "application/json"}]

case HTTPoison.put(url, "", headers, http_opts()) do
{:ok, %HTTPoison.Response{status_code: code, body: body}} when code >= 200 and code < 300 ->
case Req.put(url, [headers: headers, body: ""] ++ http_opts()) do
{:ok, %Req.Response{status: code, body: body}} when code >= 200 and code < 300 ->
decode_json(body)

{:ok, %HTTPoison.Response{status_code: code, body: body}} ->
{:ok, %Req.Response{status: code, body: body}} ->
{:error, "Bitbucket Data Center API #{code}: #{inspect(body)}"}

{:error, reason} ->
Expand Down Expand Up @@ -154,6 +154,6 @@ defmodule Console.AI.Tools.Workbench.Integration.BitbucketDatacenter.Client do

defp http_opts,
do:
Application.get_env(:console, :httpoison_bitbucket_datacenter_options, []) ++
[recv_timeout: 60_000]
Console.Utils.HTTP.provider_options(:httpoison_bitbucket_datacenter_options, :req_bitbucket_datacenter_options) ++
[receive_timeout: 60_000, decode_body: false, retry: false]
end
30 changes: 17 additions & 13 deletions lib/console/ai/tools/workbench/integration/github/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ defmodule Console.AI.Tools.Workbench.Integration.Github.Client do
def plain_get(%Tentacat.Client{} = client, path, extra_headers \\ []) when is_binary(path) do
url = client.endpoint <> path

case HTTPoison.request(:get, url, "", request_headers(client, extra_headers), request_options(client)) do
{:ok, %HTTPoison.Response{status_code: code, body: body}} when code >= 200 and code < 300 ->
case Req.request(req_opts(:get, url, "", request_headers(client, extra_headers), request_options(client))) do
{:ok, %Req.Response{status: code, body: body}} when code >= 200 and code < 300 ->
{:ok, body}

{:ok, %HTTPoison.Response{status_code: code, body: body}} ->
{:ok, %Req.Response{status: code, body: body}} ->
{:error, "GitHub API #{code}: #{inspect(body)}"}

{:error, reason} ->
Expand Down Expand Up @@ -112,15 +112,20 @@ defmodule Console.AI.Tools.Workbench.Integration.Github.Client do
defp json_request(method, %Tentacat.Client{} = client, path, opts \\ []) do
url = client.endpoint <> path

case HTTPoison.request(method, url, "", json_headers(client), request_options(client)) do
{:ok, %HTTPoison.Response{status_code: code, body: body} = resp} ->
case Req.request(req_opts(method, url, "", json_headers(client), request_options(client))) do
{:ok, %Req.Response{status: code, body: body} = resp} ->
response(method, code, decode_json_body(body), resp, opts)

{:error, reason} ->
Http.error("GitHub", reason)
end
end

defp req_opts(method, url, body, headers, options) do
[method: method, url: url, body: body, headers: headers, decode_body: false, retry: false] ++
Console.Utils.HTTP.req_options(options)
end

defp decode_json_body(body) when body in [nil, ""], do: %{}

defp decode_json_body(body) do
Expand All @@ -130,21 +135,20 @@ defmodule Console.AI.Tools.Workbench.Integration.Github.Client do
end
end

defp response(:get, code, body, %HTTPoison.Response{} = resp, pagination: :manual),
defp response(:get, code, body, %Req.Response{} = resp, pagination: :manual),
do: {{code, body, resp}, next_url(resp), nil}

defp response(:get, code, body, %HTTPoison.Response{} = resp, _) when is_list(body),
defp response(:get, code, body, %Req.Response{} = resp, _) when is_list(body),
do: {{code, body, resp}, next_url(resp), nil}

defp response(_, code, body, %HTTPoison.Response{} = resp, _),
defp response(_, code, body, %Req.Response{} = resp, _),
do: {code, body, resp}

defp next_url(%HTTPoison.Response{headers: headers}) do
Enum.find_value(headers, fn
{"Link", value} -> next_url(value)
{"link", value} -> next_url(value)
defp next_url(%Req.Response{} = resp) do
case Req.Response.get_header(resp, "link") do
[value | _] -> next_url(value)
_ -> nil
end)
end
end

defp next_url(value) when is_binary(value) do
Expand Down
8 changes: 4 additions & 4 deletions lib/console/ai/tools/workbench/integration/github/response.ex
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ defmodule Console.AI.Tools.Workbench.Integration.Github.Response do

defp query_param(_, _), do: nil

defp header(%HTTPoison.Response{headers: headers}, key) do
Enum.find_value(headers, fn
{^key, value} -> value
defp header(%Req.Response{} = resp, key) do
case Req.Response.get_header(resp, String.downcase(key)) do
[value | _] -> value
_ -> nil
end)
end
end

defp header(_, _), do: nil
Expand Down
20 changes: 10 additions & 10 deletions lib/console/ai/tools/workbench/integration/gitlab/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ defmodule Console.AI.Tools.Workbench.Integration.Gitlab.Client do
url = base <> path <> Query.query_string(query)
headers = [{"PRIVATE-TOKEN", token}]

case HTTPoison.get(url, headers, http_opts()) do
{:ok, %HTTPoison.Response{status_code: code, body: body}} when code >= 200 and code < 300 ->
case Req.get(url, [headers: headers] ++ http_opts()) do
{:ok, %Req.Response{status: code, body: body}} when code >= 200 and code < 300 ->
decode_json(body)

{:ok, %HTTPoison.Response{status_code: code, body: body}} ->
{:ok, %Req.Response{status: code, body: body}} ->
{:error, "GitLab API #{code}: #{inspect(body)}"}

{:error, reason} ->
Expand All @@ -57,11 +57,11 @@ defmodule Console.AI.Tools.Workbench.Integration.Gitlab.Client do
url = base <> path <> Query.query_string(query)
headers = [{"PRIVATE-TOKEN", token}]

case HTTPoison.post(url, "", headers, http_opts()) do
{:ok, %HTTPoison.Response{status_code: code, body: body}} when code >= 200 and code < 300 ->
case Req.post(url, [headers: headers, body: ""] ++ http_opts()) do
{:ok, %Req.Response{status: code, body: body}} when code >= 200 and code < 300 ->
decode_json(body)

{:ok, %HTTPoison.Response{status_code: code, body: body}} ->
{:ok, %Req.Response{status: code, body: body}} ->
{:error, "GitLab API #{code}: #{inspect(body)}"}

{:error, reason} ->
Expand All @@ -76,11 +76,11 @@ defmodule Console.AI.Tools.Workbench.Integration.Gitlab.Client do
headers = [{"PRIVATE-TOKEN", token}, {"Content-Type", "application/json"}]
encoded = Jason.encode!(body_map)

case HTTPoison.post(url, encoded, headers, http_opts()) do
{:ok, %HTTPoison.Response{status_code: code, body: body}} when code >= 200 and code < 300 ->
case Req.post(url, [headers: headers, body: encoded] ++ http_opts()) do
{:ok, %Req.Response{status: code, body: body}} when code >= 200 and code < 300 ->
decode_json(body)

{:ok, %HTTPoison.Response{status_code: code, body: body}} ->
{:ok, %Req.Response{status: code, body: body}} ->
{:error, "GitLab API #{code}: #{inspect(body)}"}

{:error, reason} ->
Expand All @@ -98,7 +98,7 @@ defmodule Console.AI.Tools.Workbench.Integration.Gitlab.Client do
end

defp http_opts,
do: Application.get_env(:console, :httpoison_gitlab_options, []) ++ [recv_timeout: 60_000]
do: Console.Utils.HTTP.provider_options(:httpoison_gitlab_options, :req_gitlab_options) ++ [receive_timeout: 60_000, decode_body: false, retry: false]

@doc false
def encode_project_id(project) when is_integer(project), do: Integer.to_string(project)
Expand Down
2 changes: 1 addition & 1 deletion lib/console/ai/tools/workbench/integration/http.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ defmodule Console.AI.Tools.Workbench.Integration.Http do
@moduledoc false

@spec error(String.t(), term()) :: {:error, String.t()}
def error(service, %HTTPoison.Error{reason: reason}),
def error(service, %Req.TransportError{reason: reason}),
do: {:error, "#{service} request failed: #{format_reason(reason)}"}

def error(service, reason),
Expand Down
Loading
Loading