Packages

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

Current section

Files

Jump to
pig src pig@supervisor.erl
Raw

src/pig@supervisor.erl

-module(pig@supervisor).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/pig/supervisor.gleam").
-export([start_supervised/2, run_with_timeout/3, run/2, stop/1]).
-export_type([supervised_agent/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(
" Supervised agent — wraps agent in OTP static supervisor.\n"
"\n"
" The easy path: `start_supervised(config)` gives you an agent\n"
" managed by a OneForOne supervisor. Advanced users can still\n"
" use `pig.start(config)` for standalone agents.\n"
).
-type supervised_agent() :: {supervised_agent,
gleam@erlang@process:subject(pig@agent@runtime:runtime_msg()),
gleam@erlang@process:pid_()}.
-file("src/pig/supervisor.gleam", 35).
?DOC(
" Start a supervised agent from an AgentConfig and consumer specs.\n"
"\n"
" Spawns a nested OneForOne static supervisor containing:\n"
" - An event subtree (dispatcher + consumers)\n"
" - The agent actor\n"
"\n"
" The dispatcher and agent are named so Subjects can be recovered after\n"
" supervisor start. Returns a `SupervisedAgent` handle.\n"
).
-spec start_supervised(
pig@agent@state:agent_config(),
list(pig@obs@consumer_spec:consumer_spec())
) -> {ok, supervised_agent()} | {error, gleam@otp@actor:start_error()}.
start_supervised(Agent_config, Consumer_specs) ->
Dispatcher_name = gleam_erlang_ffi:new_name(<<"pig_event_dispatcher"/utf8>>),
Agent_name = gleam_erlang_ffi:new_name(<<"pig_agent"/utf8>>),
Event_tree = begin
_pipe = gleam@otp@static_supervisor:new(one_for_all),
_pipe@1 = gleam@otp@static_supervisor:add(
_pipe,
pig@obs@dispatcher:supervised(Dispatcher_name)
),
gleam@list:fold(
Consumer_specs,
_pipe@1,
fun(Builder, Entry) ->
gleam@otp@static_supervisor:add(
Builder,
erlang:element(2, Entry)
)
end
)
end,
App_tree = begin
_pipe@2 = gleam@otp@static_supervisor:new(one_for_one),
_pipe@3 = gleam@otp@static_supervisor:add(
_pipe@2,
gleam@otp@static_supervisor:supervised(Event_tree)
),
gleam@otp@static_supervisor:add(
_pipe@3,
pig@agent@runtime:supervised(
Agent_config,
Dispatcher_name,
Agent_name
)
)
end,
case gleam@otp@static_supervisor:start(App_tree) of
{ok, Started} ->
Dispatcher_subject = gleam@erlang@process:named_subject(
Dispatcher_name
),
Agent_subject = gleam@erlang@process:named_subject(Agent_name),
gleam@list:each(
Consumer_specs,
fun(Entry@1) ->
Consumer_subject = gleam@erlang@process:named_subject(
erlang:element(3, Entry@1)
),
gleam@erlang@process:send(
Dispatcher_subject,
{register_consumer, Consumer_subject}
)
end
),
{ok, {supervised_agent, Agent_subject, erlang:element(2, Started)}};
{error, E} ->
{error, E}
end.
-file("src/pig/supervisor.gleam", 88).
?DOC(" Run a prompt against the supervised agent with an explicit timeout.\n").
-spec run_with_timeout(supervised_agent(), binary(), integer()) -> {ok,
pig@ai@message:message()} |
{error, pig@ai@error:ai_error()}.
run_with_timeout(Sup, Prompt, Timeout_ms) ->
pig@agent@runtime:run(erlang:element(2, Sup), Prompt, Timeout_ms).
-file("src/pig/supervisor.gleam", 83).
?DOC(" Run a prompt against the supervised agent with a 120-second timeout.\n").
-spec run(supervised_agent(), binary()) -> {ok, pig@ai@message:message()} |
{error, pig@ai@error:ai_error()}.
run(Sup, Prompt) ->
run_with_timeout(Sup, Prompt, 120000).
-file("src/pig/supervisor.gleam", 100).
?DOC(
" Stop the supervised agent.\n"
"\n"
" Sends an exit signal to the supervisor process. OTP cascades\n"
" shutdown to the agent child process.\n"
).
-spec stop(supervised_agent()) -> nil.
stop(Sup) ->
gleam@erlang@process:send_exit(erlang:element(3, Sup)).