Packages

A Gleam library for building and orchestrating agents on the BEAM.

Current section

Files

Jump to
pig src pig@tool@web_fetch.erl
Raw

src/pig@tool@web_fetch.erl

-module(pig@tool@web_fetch).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/pig/tool/web_fetch.gleam").
-export([tool/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" Built-in `web_fetch` tool for simple HTTP GET requests.\n"
"\n"
" Returns the HTTP status and response body as JSON.\n"
" Intended as a ready-made tool that library users can register\n"
" with `pig.with_tool(web_fetch.tool())`.\n"
).
-file("src/pig/tool/web_fetch.gleam", 119).
?DOC(" Truncate a string to at most `max` characters, appending \"...\" if truncated.\n").
-spec string_truncate(binary(), integer()) -> binary().
string_truncate(S, Max) ->
case string:length(S) =< Max of
true ->
S;
false ->
<<(gleam@string:slice(S, 0, Max))/binary, "..."/utf8>>
end.
-file("src/pig/tool/web_fetch.gleam", 111).
-spec format_socket_error(gleam@httpc:connect_error()) -> binary().
format_socket_error(Err) ->
case Err of
{posix, Code} ->
Code;
{tls_alert, Code@1, Detail} ->
<<<<Code@1/binary, ": "/utf8>>/binary, Detail/binary>>
end.
-file("src/pig/tool/web_fetch.gleam", 98).
?DOC(" Format an httpc error into a human-readable string.\n").
-spec format_error(gleam@httpc:http_error()) -> binary().
format_error(Err) ->
case Err of
response_timeout ->
<<"request timed out"/utf8>>;
invalid_utf8_response ->
<<"response body was not valid UTF-8"/utf8>>;
{failed_to_connect, Ip4, Ip6} ->
<<<<<<<<"failed to connect (ipv4: "/utf8,
(format_socket_error(Ip4))/binary>>/binary,
", ipv6: "/utf8>>/binary,
(format_socket_error(Ip6))/binary>>/binary,
")"/utf8>>
end.
-file("src/pig/tool/web_fetch.gleam", 76).
?DOC(" Convert a successful response to JSON or a ToolError for non-2xx.\n").
-spec handle_response(gleam@http@response:response(binary())) -> {ok,
gleam@json:json()} |
{error, pig@tool:tool_error()}.
handle_response(Resp) ->
case erlang:element(2, Resp) of
S when (S >= 200) andalso (S < 300) ->
{ok,
gleam@json:object(
[{<<"status"/utf8>>,
gleam@json:int(erlang:element(2, Resp))},
{<<"body"/utf8>>,
gleam@json:string(erlang:element(4, Resp))}]
)};
Status ->
{error,
{tool_error,
<<<<<<"HTTP "/utf8,
(erlang:integer_to_binary(Status))/binary>>/binary,
": "/utf8>>/binary,
(string_truncate(erlang:element(4, Resp), 500))/binary>>}}
end.
-file("src/pig/tool/web_fetch.gleam", 43).
?DOC(" Handler for the web_fetch tool.\n").
-spec handle(pig@tool:tool_call_context(), gleam@dynamic:dynamic_()) -> {ok,
gleam@json:json()} |
{error, pig@tool:tool_error()}.
handle(_, Args) ->
gleam@result:'try'(
begin
_pipe = gleam@dynamic@decode:run(
Args,
gleam@dynamic@decode:field(
<<"url"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun gleam@dynamic@decode:success/1
)
),
gleam@result:map_error(
_pipe,
fun(_) ->
{tool_error,
<<"Invalid arguments: expected {\"url\": \"<url>\"}"/utf8>>}
end
)
end,
fun(Url) ->
logging:log(info, <<"web_fetch: GET "/utf8, Url/binary>>),
gleam@result:'try'(
begin
_pipe@1 = gleam@http@request:to(Url),
gleam@result:map_error(
_pipe@1,
fun(_) ->
{tool_error, <<"Invalid URL: "/utf8, Url/binary>>}
end
)
end,
fun(Req) ->
gleam@result:'try'(
begin
_pipe@2 = gleam@httpc:send(Req),
gleam@result:map_error(
_pipe@2,
fun(Err) ->
{tool_error,
<<"HTTP request failed: "/utf8,
(format_error(Err))/binary>>}
end
)
end,
fun(Resp) -> handle_response(Resp) end
)
end
)
end
).
-file("src/pig/tool/web_fetch.gleam", 30).
?DOC(
" Create a `web_fetch` tool.\n"
"\n"
" The tool performs a GET request to the given URL and returns:\n"
"\n"
" ```json\n"
" {\"status\": 200, \"body\": \"<response body>\"}\n"
" ```\n"
"\n"
" Returns a `ToolError` for invalid URLs, network failures, or non-2xx responses.\n"
).
-spec tool() -> pig@tool:tool().
tool() ->
{tool,
{tool_definition,
<<"web_fetch"/utf8>>,
<<"Fetch the contents of a URL via HTTP GET. "/utf8,
"Returns the response status code and body."/utf8>>,
jscheam@schema:object(
[jscheam@schema:prop(<<"url"/utf8>>, jscheam@schema:string())]
)},
fun handle/2}.