-module(pig@agent@runtime). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/pig/agent/runtime.gleam"). -export([start_with_state/2, start/1, run/3, run_continue/2, stop/1, history/2, try_run/3, try_run_continue/2, supervised/3]). -export_type([runtime_config/0, runtime_msg/0, runtime_state/0, blocked_tool/0, tool_result/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( " Sans-IO runtime interpreter for the pig agent.\n" "\n" " The runtime is an OTP actor that:\n" " 1. Receives prompts (Run) or control messages (Stop)\n" " 2. Calls `update.update(state, msg)` — pure state machine\n" " 3. For each effect, applies hooks then executes\n" " 4. Produces SessionEvent values and sends to dispatcher\n" " 5. Feeds effect results back as new AgentMsg values\n" "\n" " The core logic (update.gleam) is pure. This module is all IO.\n" ). -type runtime_config() :: {runtime_config, fun((list(pig_protocol@message:message()), list(pig_protocol@tool_definition:tool_definition())) -> {ok, pig_protocol@inference:inference_result()} | {error, pig_protocol@error:ai_error()}), pig@tool:tool_registry(), list(pig@hooks:hooks()), gleam@erlang@process:subject(pig@obs@dispatcher:dispatcher_message()), binary(), integer()}. -type runtime_msg() :: {run, binary(), gleam@erlang@process:subject({ok, pig_protocol@message:message()} | {error, pig_protocol@error:ai_error()})} | {continue, gleam@erlang@process:subject({ok, pig_protocol@message:message()} | {error, pig_protocol@error:ai_error()})} | {get_history, gleam@erlang@process:subject(list(pig_protocol@message:message()))} | stop. -type runtime_state() :: {runtime_state, pig@agent@state:agent_state(), runtime_config()}. -type blocked_tool() :: {blocked_tool, pig_protocol@message:tool_call(), binary(), binary()}. -type tool_result() :: {tool_result, binary(), {ok, gleam@json:json()} | {error, pig@tool:tool_error()}, integer()}. -file("src/pig/agent/runtime.gleam", 682). -spec find_result(list(tool_result()), binary()) -> {ok, {{ok, gleam@json:json()} | {error, pig@tool:tool_error()}, integer()}} | {error, nil}. find_result(Results, Call_id) -> case gleam@list:find( Results, fun(R) -> erlang:element(2, R) =:= Call_id end ) of {ok, R@1} -> {ok, {erlang:element(3, R@1), erlang:element(4, R@1)}}; {error, nil} -> {error, nil} end. -file("src/pig/agent/runtime.gleam", 675). -spec find_blocked(list(blocked_tool()), binary()) -> {ok, blocked_tool()} | {error, nil}. find_blocked(Blocked, Call_id) -> gleam@list:find( Blocked, fun(B) -> erlang:element(2, erlang:element(2, B)) =:= Call_id end ). -file("src/pig/agent/runtime.gleam", 699). -spec emit_hook_acted_list( gleam@erlang@process:subject(pig@obs@dispatcher:dispatcher_message()), list(binary()), pig@obs@events:hook_point(), binary(), binary() ) -> nil. emit_hook_acted_list(Disp, Transformer_names, Hook, Action_type, Description) -> gleam@list:each( Transformer_names, fun(Name) -> pig@obs@emit:to_dispatcher( Disp, {hook_acted, Name, Hook, {hook_action_detail, Action_type, Description}} ) end ). -file("src/pig/agent/runtime.gleam", 692). -spec is_error({ok, any()} | {error, any()}) -> boolean(). is_error(Result) -> case Result of {ok, _} -> false; {error, _} -> true end. -file("src/pig/agent/runtime.gleam", 636). -spec spawn_and_collect( runtime_config(), list(pig_protocol@message:tool_call()) ) -> list(tool_result()). spawn_and_collect(Config, Calls) -> Disp = erlang:element(5, Config), Pairs = gleam@list:map( Calls, fun(Call) -> Reply_subject = gleam@erlang@process:new_subject(), Pid = proc_lib:spawn_link( fun() -> pig@obs@emit:to_dispatcher(Disp, {tool_started, Call}), Start_time = pig@obs@events:system_time(), Result = pig@tool@execution:execute_tool( erlang:element(3, Config), Call ), Duration = pig@obs@events:system_time() - Start_time, gleam@erlang@process:send( Reply_subject, {tool_result, erlang:element(2, Call), Result, Duration} ) end ), {Pid, Reply_subject, erlang:element(2, Call)} end ), Timeout_ms = 5000, gleam@list:map( Pairs, fun(Pair) -> {Pid@1, Subject, Call_id} = Pair, case gleam@erlang@process:'receive'(Subject, Timeout_ms) of {ok, Result@1} -> Result@1; {error, nil} -> gleam@erlang@process:kill(Pid@1), logging:log( error, <<<<"Tool execution timed out after "/utf8, (erlang:integer_to_binary(Timeout_ms))/binary>>/binary, "ms"/utf8>> ), {tool_result, Call_id, {error, {tool_error, <<"Tool execution timed out"/utf8>>}}, Timeout_ms} end end ). -file("src/pig/agent/runtime.gleam", 612). -spec partition_by_hook_decision( list(pig@hooks:hooks()), list(pig_protocol@message:tool_call()) ) -> {list(blocked_tool()), list(pig_protocol@message:tool_call())}. partition_by_hook_decision(Hooks_list, Calls) -> gleam@list:fold( Calls, {[], []}, fun(Acc, Call) -> {Blocked_acc, Allowed_acc} = Acc, Hook_event = {tool_call_event, erlang:element(3, Call), erlang:element(2, Call), erlang:element(4, Call)}, case pig@hooks:decide_tool_call(Hooks_list, Hook_event) of tool_allowed -> {Blocked_acc, lists:append(Allowed_acc, [Call])}; {tool_blocked, Hook_name, Reason} -> {lists:append( Blocked_acc, [{blocked_tool, Call, Hook_name, Reason}] ), Allowed_acc} end end ). -file("src/pig/agent/runtime.gleam", 496). ?DOC( " Execute ExecuteTools: apply tool call hooks, execute allowed tools\n" " in parallel, apply result hooks, emit events.\n" ). -spec execute_tools_effect( runtime_config(), pig@agent@state:agent_state(), list(pig_protocol@message:tool_call()), fun((list({pig_protocol@message:tool_call(), {ok, gleam@json:json()} | {error, pig@tool:tool_error()}})) -> pig@agent@msg:agent_msg()) ) -> {pig@agent@state:agent_state(), pig@agent@msg:agent_msg()}. execute_tools_effect(Config, Agent_st, Calls, On_results) -> Disp = erlang:element(5, Config), {Blocked, Allowed} = partition_by_hook_decision( erlang:element(4, Config), Calls ), gleam@list:each( Blocked, fun(B) -> pig@obs@emit:to_dispatcher( Disp, {tool_blocked, erlang:element(2, B), erlang:element(3, B), erlang:element(4, B)} ), pig@obs@emit:to_dispatcher( Disp, {hook_acted, erlang:element(3, B), before_tool_call, {hook_action_detail, <<"block"/utf8>>, <<"Blocked tool: "/utf8, (erlang:element(4, B))/binary>>}} ) end ), Results = spawn_and_collect(Config, Allowed), _ = gleam@list:map( Allowed, fun(Call) -> {Result@1, Duration@1} = case find_result( Results, erlang:element(2, Call) ) of {ok, {Result, Duration}} -> {Result, Duration}; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"pig/agent/runtime"/utf8>>, function => <<"execute_tools_effect"/utf8>>, line => 538, value => _assert_fail, start => 18021, 'end' => 18087, pattern_start => 18032, pattern_end => 18055}) end, Raw_content = case Result@1 of {ok, Json_result} -> gleam@json:to_string(Json_result); {error, Tool_err} -> <<"Tool error: "/utf8, (erlang:element(2, Tool_err))/binary>> end, Result_event = {tool_result_event, erlang:element(3, Call), erlang:element(2, Call), Raw_content, is_error(Result@1), Duration@1}, Final_content = case pig@hooks:decide_tool_result( erlang:element(4, Config), Result_event ) of {result_unchanged, _} -> Raw_content; {result_transformed, Final_event, Transformers} -> emit_hook_acted_list( Disp, Transformers, after_tool_call, <<"transform"/utf8>>, <<"Transformed result"/utf8>> ), erlang:element(4, Final_event) end, pig@obs@emit:to_dispatcher( Disp, {tool_executed, Call, Final_content, Duration@1} ) end ), All_results = gleam@list:map( Calls, fun(Call@1) -> case find_blocked(Blocked, erlang:element(2, Call@1)) of {ok, B@1} -> {Call@1, {error, {tool_error, <<<<<<"Tool blocked by '"/utf8, (erlang:element(3, B@1))/binary>>/binary, "': "/utf8>>/binary, (erlang:element(4, B@1))/binary>>}}}; {error, nil} -> Res@1 = case find_result(Results, erlang:element(2, Call@1)) of {ok, {Res, _}} -> Res; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"pig/agent/runtime"/utf8>>, function => <<"execute_tools_effect"/utf8>>, line => 589, value => _assert_fail@1, start => 19523, 'end' => 19582, pattern_start => 19534, pattern_end => 19550}) end, {Call@1, Res@1} end end ), {Agent_st, On_results(All_results)}. -file("src/pig/agent/runtime.gleam", 414). ?DOC( " Execute CallProvider: apply before_inference hooks, call provider,\n" " emit events, fire notification hooks.\n" ). -spec execute_call_provider( runtime_config(), pig@agent@state:agent_state(), list(pig_protocol@message:message()), list(pig_protocol@tool_definition:tool_definition()), fun(({ok, pig_protocol@inference:inference_result()} | {error, pig_protocol@error:ai_error()}) -> pig@agent@msg:agent_msg()) ) -> {pig@agent@state:agent_state(), pig@agent@msg:agent_msg()}. execute_call_provider(Config, Agent_st, Messages, Tools, On_response) -> Disp = erlang:element(5, Config), Model = erlang:element(6, Config), Before_event = {before_inference_event, Model, Messages}, Final_msgs = case pig@hooks:decide_messages( erlang:element(4, Config), Before_event ) of {messages_unchanged, _} -> Messages; {messages_replaced, Final_messages, Transformers} -> emit_hook_acted_list( Disp, Transformers, before_inference, <<"transform"/utf8>>, <<"Transformed messages before inference"/utf8>> ), Final_messages end, Msg_count = erlang:length(Final_msgs), pig@obs@emit:to_dispatcher(Disp, {inference_started, Model, Msg_count}), Start_time = pig@obs@events:system_time(), Result = case (erlang:element(2, Config))(Final_msgs, Tools) of {ok, Inference_result} -> Msg = erlang:element(2, Inference_result), Meta = erlang:element(3, Inference_result), Duration = pig@obs@events:system_time() - Start_time, Response_model = case erlang:element(3, Meta) of {some, _} = M -> M; none -> {some, Model} end, pig@obs@emit:to_dispatcher( Disp, {inference_completed, Msg, erlang:element(2, Meta), Response_model, erlang:element(4, Meta), erlang:element(5, Meta), erlang:element(6, Meta), Duration, erlang:element(3, Agent_st)} ), pig@hooks:notify_after_inference( erlang:element(4, Config), {after_inference_event, Model, Msg, Duration} ), {ok, Inference_result}; {error, E} -> Duration@1 = pig@obs@events:system_time() - Start_time, pig@obs@emit:to_dispatcher( Disp, {inference_failed, E, Duration@1, erlang:element(3, Agent_st)} ), pig@hooks:notify_error( erlang:element(4, Config), {error_event, Model, E} ), {error, E} end, {Agent_st, On_response(Result)}. -file("src/pig/agent/runtime.gleam", 399). ?DOC(" Execute a single effect: apply hooks, execute, emit events.\n"). -spec execute_effect( runtime_config(), pig@agent@state:agent_state(), pig@agent@effect:effect(pig@agent@msg:agent_msg()) ) -> {pig@agent@state:agent_state(), pig@agent@msg:agent_msg()}. execute_effect(Config, Agent_st, Eff) -> case Eff of {call_provider, Messages, Tools, On_response} -> execute_call_provider( Config, Agent_st, Messages, Tools, On_response ); {execute_tools, Calls, On_results} -> execute_tools_effect(Config, Agent_st, Calls, On_results) end. -file("src/pig/agent/runtime.gleam", 261). -spec do_loop( runtime_config(), pig@agent@state:agent_state(), pig@agent@msg:agent_msg() ) -> {pig@agent@state:agent_state(), {ok, pig_protocol@message:message()} | {error, pig_protocol@error:ai_error()}}. do_loop(Config, Agent_st, M) -> Result = pig@agent@update:update(Agent_st, M), case Result of {done, Final_st, Msg} -> {Final_st, {ok, Msg}}; {failed, Final_st@1, E} -> {Final_st@1, {error, E}}; {continue, New_st, Effs} -> {Updated_st, Response_msgs} = gleam@list:fold( Effs, {New_st, []}, fun(Acc, Eff) -> {St_acc, Msgs_acc} = Acc, {New_st_acc, Response_msg} = execute_effect( Config, St_acc, Eff ), {New_st_acc, lists:append(Msgs_acc, [Response_msg])} end ), case Response_msgs of [First_msg | _] -> do_loop(Config, Updated_st, First_msg); [] -> {Updated_st, {error, {api_error, <<"no response from effects"/utf8>>}}} end end. -file("src/pig/agent/runtime.gleam", 339). ?DOC( " Decide how to resume based on the last assistant message's stop_reason\n" " and tool_calls.\n" ). -spec resume_from_assistant( runtime_config(), pig@agent@state:agent_state(), list(pig_protocol@message:tool_call()), gleam@option:option(pig_protocol@stop_reason:stop_reason()) ) -> {pig@agent@state:agent_state(), {ok, pig_protocol@message:message()} | {error, pig_protocol@error:ai_error()}}. resume_from_assistant(Config, St, Tool_calls, Sr) -> case Sr of {some, tool_use} -> {_, Agent_msg} = execute_tools_effect( Config, St, Tool_calls, fun(Results) -> {tool_results, Results} end ), do_loop(Config, St, Agent_msg); {some, stop} -> Msg@1 = case gleam@list:last(erlang:element(3, St)) of {ok, Msg} -> Msg; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"pig/agent/runtime"/utf8>>, function => <<"resume_from_assistant"/utf8>>, line => 357, value => _assert_fail, start => 12351, 'end' => 12393, pattern_start => 12362, pattern_end => 12369}) end, {St, {ok, Msg@1}}; {some, length} -> {St_after, Provider_msg} = execute_call_provider( Config, St, pig@agent@state:messages_for_provider(St), pig@agent@state:tool_definitions(St), fun(R) -> {provider_responded, gleam@result:map( R, fun(Ir) -> erlang:element(2, Ir) end )} end ), do_loop(Config, St_after, Provider_msg); {some, error} -> {St_after, Provider_msg} = execute_call_provider( Config, St, pig@agent@state:messages_for_provider(St), pig@agent@state:tool_definitions(St), fun(R) -> {provider_responded, gleam@result:map( R, fun(Ir) -> erlang:element(2, Ir) end )} end ), do_loop(Config, St_after, Provider_msg); {some, {unknown, _}} -> {St_after, Provider_msg} = execute_call_provider( Config, St, pig@agent@state:messages_for_provider(St), pig@agent@state:tool_definitions(St), fun(R) -> {provider_responded, gleam@result:map( R, fun(Ir) -> erlang:element(2, Ir) end )} end ), do_loop(Config, St_after, Provider_msg); none -> case Tool_calls of [] -> Msg@3 = case gleam@list:last(erlang:element(3, St)) of {ok, Msg@2} -> Msg@2; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"pig/agent/runtime"/utf8>>, function => <<"resume_from_assistant"/utf8>>, line => 381, value => _assert_fail@1, start => 13150, 'end' => 13192, pattern_start => 13161, pattern_end => 13168}) end, {St, {ok, Msg@3}}; Calls -> {_, Agent_msg@1} = execute_tools_effect( Config, St, Calls, fun(Results@1) -> {tool_results, Results@1} end ), do_loop(Config, St, Agent_msg@1) end end. -file("src/pig/agent/runtime.gleam", 294). ?DOC( " Resume the agent loop from its current history.\n" "\n" " Determines the entry point by inspecting the last message in history.\n" " This enables the durability pattern: an external system checkpoints\n" " messages, and on retry, rebuilds history from those checkpoints.\n" ). -spec resume_from_history(runtime_config(), pig@agent@state:agent_state()) -> {pig@agent@state:agent_state(), {ok, pig_protocol@message:message()} | {error, pig_protocol@error:ai_error()}}. resume_from_history(Config, St) -> case gleam@list:last(erlang:element(3, St)) of {error, _} -> {St, {error, {api_error, <<"no history to continue"/utf8>>}}}; {ok, Last_msg} -> case Last_msg of {assistant, _, Tool_calls, _, Sr} -> resume_from_assistant(Config, St, Tool_calls, Sr); {user, _} -> {St_after, Provider_msg} = execute_call_provider( Config, St, pig@agent@state:messages_for_provider(St), pig@agent@state:tool_definitions(St), fun(R) -> {provider_responded, gleam@result:map( R, fun(Ir) -> erlang:element(2, Ir) end )} end ), do_loop(Config, St_after, Provider_msg); {tool, _, _} -> {St_after, Provider_msg} = execute_call_provider( Config, St, pig@agent@state:messages_for_provider(St), pig@agent@state:tool_definitions(St), fun(R) -> {provider_responded, gleam@result:map( R, fun(Ir) -> erlang:element(2, Ir) end )} end ), do_loop(Config, St_after, Provider_msg); {system, _} -> {St, {error, {api_error, <<"unexpected system message at end of history"/utf8>>}}} end end. -file("src/pig/agent/runtime.gleam", 253). ?DOC( " Execute the sans-IO loop: call update, interpret effects, feed back.\n" " Returns the final agent state and the result.\n" ). -spec execute_loop( runtime_config(), pig@agent@state:agent_state(), pig@agent@msg:agent_msg() ) -> {pig@agent@state:agent_state(), {ok, pig_protocol@message:message()} | {error, pig_protocol@error:ai_error()}}. execute_loop(Config, Agent_st, Initial_msg) -> do_loop(Config, Agent_st, Initial_msg). -file("src/pig/agent/runtime.gleam", 212). -spec handle_message(runtime_state(), runtime_msg()) -> gleam@otp@actor:next(runtime_state(), runtime_msg()). handle_message(St, M) -> case M of {run, Prompt, Reply_to} -> Agent_st = {agent_state, erlang:element(2, erlang:element(2, St)), erlang:element(3, erlang:element(2, St)), 0}, Result = execute_loop( erlang:element(3, St), Agent_st, {user_prompt, Prompt} ), {Final_state, Outcome} = Result, gleam@erlang@process:send(Reply_to, Outcome), gleam@otp@actor:continue( {runtime_state, Final_state, erlang:element(3, St)} ); {continue, Reply_to@1} -> Agent_st@1 = {agent_state, erlang:element(2, erlang:element(2, St)), erlang:element(3, erlang:element(2, St)), 0}, {Final_state@1, Outcome@1} = resume_from_history( erlang:element(3, St), Agent_st@1 ), gleam@erlang@process:send(Reply_to@1, Outcome@1), gleam@otp@actor:continue( {runtime_state, Final_state@1, erlang:element(3, St)} ); {get_history, Reply_to@2} -> gleam@erlang@process:send( Reply_to@2, erlang:element(3, erlang:element(2, St)) ), gleam@otp@actor:continue(St); stop -> gleam@otp@actor:stop() end. -file("src/pig/agent/runtime.gleam", 103). ?DOC( " Start the runtime actor with a pre-built state.\n" " Used by `pig.gleam` when session replay needs to happen before start.\n" ). -spec start_with_state(runtime_config(), runtime_state()) -> {ok, gleam@erlang@process:subject(runtime_msg())} | {error, gleam@otp@actor:start_error()}. start_with_state(_, Initial_state) -> Builder = begin _pipe = gleam@otp@actor:new(Initial_state), gleam@otp@actor:on_message(_pipe, fun handle_message/2) end, case gleam@otp@actor:start(Builder) of {ok, Started} -> {ok, erlang:element(3, Started)}; {error, E} -> {error, E} end. -file("src/pig/agent/runtime.gleam", 78). ?DOC(" Start the runtime actor with the given configuration.\n"). -spec start(runtime_config()) -> {ok, gleam@erlang@process:subject(runtime_msg())} | {error, gleam@otp@actor:start_error()}. start(Config) -> Agent_config = {agent_config, erlang:element(2, Config), erlang:element(3, Config), none, erlang:element(7, Config), erlang:element(6, Config), none, none, none, none, none, none}, Initial_state = {runtime_state, pig@agent@state:new(Agent_config), Config}, start_with_state(Config, Initial_state). -file("src/pig/agent/runtime.gleam", 117). ?DOC(" Send a prompt to the runtime and wait for a response.\n"). -spec run(gleam@erlang@process:subject(runtime_msg()), binary(), integer()) -> {ok, pig_protocol@message:message()} | {error, pig_protocol@error:ai_error()}. run(Subject, Prompt, Timeout) -> gleam@otp@actor:call( Subject, Timeout, fun(Reply_to) -> {run, Prompt, Reply_to} end ). -file("src/pig/agent/runtime.gleam", 132). ?DOC( " Resume the agent loop from its current history.\n" "\n" " Looks at the last message in history to determine the entry point:\n" " - User/Tool message → call the provider\n" " - Assistant with stop_reason=ToolUse → execute pending tool calls\n" " - Assistant with stop_reason=Stop → return immediately\n" " - Assistant with stop_reason=Length/Error → re-call provider\n" ). -spec run_continue(gleam@erlang@process:subject(runtime_msg()), integer()) -> {ok, pig_protocol@message:message()} | {error, pig_protocol@error:ai_error()}. run_continue(Subject, Timeout) -> gleam@otp@actor:call( Subject, Timeout, fun(Reply_to) -> {continue, Reply_to} end ). -file("src/pig/agent/runtime.gleam", 140). ?DOC(" Send a stop message to the runtime actor.\n"). -spec stop(gleam@erlang@process:subject(runtime_msg())) -> nil. stop(Subject) -> gleam@otp@actor:send(Subject, stop). -file("src/pig/agent/runtime.gleam", 145). ?DOC(" Get the agent's current message history.\n"). -spec history(gleam@erlang@process:subject(runtime_msg()), integer()) -> list(pig_protocol@message:message()). history(Subject, Timeout) -> gleam@otp@actor:call( Subject, Timeout, fun(Reply_to) -> {get_history, Reply_to} end ). -file("src/pig/agent/runtime.gleam", 154). ?DOC( " Send a prompt to the runtime and wait for a response.\n" " Returns `Error(Nil)` if the call times out or the runtime crashes.\n" ). -spec try_run(gleam@erlang@process:subject(runtime_msg()), binary(), integer()) -> {ok, {ok, pig_protocol@message:message()} | {error, pig_protocol@error:ai_error()}} | {error, nil}. try_run(Subject, Prompt, Timeout) -> pig_agent_try_call_ffi:try_call( Subject, Timeout, fun(Reply_to) -> {run, Prompt, Reply_to} end ). -file("src/pig/agent/runtime.gleam", 164). ?DOC( " Resume the agent loop from its current history and wait for a response.\n" " Returns `Error(Nil)` if the call times out or the runtime crashes.\n" ). -spec try_run_continue(gleam@erlang@process:subject(runtime_msg()), integer()) -> {ok, {ok, pig_protocol@message:message()} | {error, pig_protocol@error:ai_error()}} | {error, nil}. try_run_continue(Subject, Timeout) -> pig_agent_try_call_ffi:try_call( Subject, Timeout, fun(Reply_to) -> {continue, Reply_to} end ). -file("src/pig/agent/runtime.gleam", 182). ?DOC( " Create a ChildSpecification for use with static_supervisor.\n" "\n" " Starts a named actor so the Subject can be recovered after\n" " supervisor start via `process.named_subject(name)`.\n" ). -spec supervised( pig@agent@state:agent_config(), gleam@erlang@process:name(pig@obs@dispatcher:dispatcher_message()), gleam@erlang@process:name(runtime_msg()) ) -> gleam@otp@supervision:child_specification(nil). supervised(Agent_config, Dispatcher_name, Name) -> gleam@otp@supervision:worker( fun() -> Runtime_config = {runtime_config, erlang:element(2, Agent_config), erlang:element(3, Agent_config), [], gleam@erlang@process:named_subject(Dispatcher_name), erlang:element(6, Agent_config), erlang:element(5, Agent_config)}, Initial_state = {runtime_state, pig@agent@state:new(Agent_config), Runtime_config}, Builder = begin _pipe = gleam@otp@actor:new(Initial_state), _pipe@1 = gleam@otp@actor:on_message( _pipe, fun handle_message/2 ), gleam@otp@actor:named(_pipe@1, Name) end, case gleam@otp@actor:start(Builder) of {ok, Started} -> {ok, {started, erlang:element(2, Started), nil}}; {error, E} -> {error, E} end end ).