-module(pig@agent@state). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/pig/agent/state.gleam"). -export([config/1, with_tools/2, with_system_prompt/2, with_max_iterations/2, with_model/2, with_agent_id/2, with_agent_name/2, with_agent_description/2, with_agent_version/2, with_provider_name/2, with_session_path/2, new/1, config_put_provider/2, add_message/2, history/1, increment_iterations/1, exceeded_max_iterations/1, tool_definitions/1, messages_for_provider/1, max_iterations_error/1]). -export_type([agent_config/0, agent_state/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( " Agent state types and configuration.\n" "\n" " `AgentConfig` holds the immutable configuration for creating an agent.\n" " `AgentState` holds the runtime state (history, iterations).\n" " State is immutable — every mutation returns a new state.\n" "\n" " Note: hooks and dispatcher are runtime concerns, stored on\n" " `PigConfig` / `RuntimeConfig`, not here. The pure core (`update.gleam`)\n" " has no knowledge of hooks or the dispatcher.\n" ). -type agent_config() :: {agent_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(), gleam@option:option(binary()), integer(), binary(), gleam@option:option(binary()), gleam@option:option(binary()), gleam@option:option(binary()), gleam@option:option(binary()), gleam@option:option(binary()), gleam@option:option(binary())}. -type agent_state() :: {agent_state, agent_config(), list(pig_protocol@message:message()), integer()}. -file("src/pig/agent/state.gleam", 48). ?DOC(" Create an AgentConfig with defaults.\n"). -spec 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()}) ) -> agent_config(). config(Provider) -> {agent_config, Provider, pig@tool:new_registry(), none, 50, <<"unknown"/utf8>>, none, none, none, none, none, none}. -file("src/pig/agent/state.gleam", 65). ?DOC(" Set the tool registry on the config.\n"). -spec with_tools(agent_config(), pig@tool:tool_registry()) -> agent_config(). with_tools(Config, Tools) -> {agent_config, erlang:element(2, Config), Tools, erlang:element(4, Config), erlang:element(5, Config), erlang:element(6, Config), erlang:element(7, Config), erlang:element(8, Config), erlang:element(9, Config), erlang:element(10, Config), erlang:element(11, Config), erlang:element(12, Config)}. -file("src/pig/agent/state.gleam", 70). ?DOC(" Set the system prompt on the config.\n"). -spec with_system_prompt(agent_config(), binary()) -> agent_config(). with_system_prompt(Config, Prompt) -> {agent_config, erlang:element(2, Config), erlang:element(3, Config), {some, Prompt}, erlang:element(5, Config), erlang:element(6, Config), erlang:element(7, Config), erlang:element(8, Config), erlang:element(9, Config), erlang:element(10, Config), erlang:element(11, Config), erlang:element(12, Config)}. -file("src/pig/agent/state.gleam", 75). ?DOC(" Set the maximum number of loop iterations before forcing termination.\n"). -spec with_max_iterations(agent_config(), integer()) -> agent_config(). with_max_iterations(Config, Max) -> {agent_config, erlang:element(2, Config), erlang:element(3, Config), erlang:element(4, Config), Max, erlang:element(6, Config), erlang:element(7, Config), erlang:element(8, Config), erlang:element(9, Config), erlang:element(10, Config), erlang:element(11, Config), erlang:element(12, Config)}. -file("src/pig/agent/state.gleam", 80). ?DOC(" Set the model name for telemetry and logging.\n"). -spec with_model(agent_config(), binary()) -> agent_config(). with_model(Config, Model) -> {agent_config, erlang:element(2, Config), erlang:element(3, Config), erlang:element(4, Config), erlang:element(5, Config), Model, erlang:element(7, Config), erlang:element(8, Config), erlang:element(9, Config), erlang:element(10, Config), erlang:element(11, Config), erlang:element(12, Config)}. -file("src/pig/agent/state.gleam", 85). ?DOC(" Set the agent ID.\n"). -spec with_agent_id(agent_config(), binary()) -> agent_config(). with_agent_id(Config, Id) -> {agent_config, erlang:element(2, Config), erlang:element(3, Config), erlang:element(4, Config), erlang:element(5, Config), erlang:element(6, Config), {some, Id}, erlang:element(8, Config), erlang:element(9, Config), erlang:element(10, Config), erlang:element(11, Config), erlang:element(12, Config)}. -file("src/pig/agent/state.gleam", 90). ?DOC(" Set the agent name.\n"). -spec with_agent_name(agent_config(), binary()) -> agent_config(). with_agent_name(Config, Name) -> {agent_config, erlang:element(2, Config), erlang:element(3, Config), erlang:element(4, Config), erlang:element(5, Config), erlang:element(6, Config), erlang:element(7, Config), {some, Name}, erlang:element(9, Config), erlang:element(10, Config), erlang:element(11, Config), erlang:element(12, Config)}. -file("src/pig/agent/state.gleam", 95). ?DOC(" Set the agent description.\n"). -spec with_agent_description(agent_config(), binary()) -> agent_config(). with_agent_description(Config, Desc) -> {agent_config, erlang:element(2, Config), erlang:element(3, Config), erlang:element(4, Config), erlang:element(5, Config), erlang:element(6, Config), erlang:element(7, Config), erlang:element(8, Config), {some, Desc}, erlang:element(10, Config), erlang:element(11, Config), erlang:element(12, Config)}. -file("src/pig/agent/state.gleam", 103). ?DOC(" Set the agent version.\n"). -spec with_agent_version(agent_config(), binary()) -> agent_config(). with_agent_version(Config, Version) -> {agent_config, erlang:element(2, Config), erlang:element(3, Config), erlang:element(4, Config), erlang:element(5, Config), erlang:element(6, Config), erlang:element(7, Config), erlang:element(8, Config), erlang:element(9, Config), {some, Version}, erlang:element(11, Config), erlang:element(12, Config)}. -file("src/pig/agent/state.gleam", 108). ?DOC(" Set the provider name.\n"). -spec with_provider_name(agent_config(), binary()) -> agent_config(). with_provider_name(Config, Name) -> {agent_config, erlang:element(2, Config), erlang:element(3, Config), erlang:element(4, Config), erlang:element(5, Config), erlang:element(6, Config), erlang:element(7, Config), erlang:element(8, Config), erlang:element(9, Config), erlang:element(10, Config), {some, Name}, erlang:element(12, Config)}. -file("src/pig/agent/state.gleam", 113). ?DOC(" Set the session path for persistence and replay.\n"). -spec with_session_path(agent_config(), binary()) -> agent_config(). with_session_path(Config, Path) -> {agent_config, erlang:element(2, Config), erlang:element(3, Config), erlang:element(4, Config), erlang:element(5, Config), erlang:element(6, Config), erlang:element(7, Config), erlang:element(8, Config), erlang:element(9, Config), erlang:element(10, Config), erlang:element(11, Config), {some, Path}}. -file("src/pig/agent/state.gleam", 118). ?DOC(" Create initial agent state from config.\n"). -spec new(agent_config()) -> agent_state(). new(Config) -> {agent_state, Config, [], 0}. -file("src/pig/agent/state.gleam", 123). ?DOC(" Replace the provider on an existing state.\n"). -spec config_put_provider( agent_state(), 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()}) ) -> agent_state(). config_put_provider(St, Provider) -> {agent_state, begin _record = erlang:element(2, St), {agent_config, Provider, erlang:element(3, _record), erlang:element(4, _record), erlang:element(5, _record), erlang:element(6, _record), erlang:element(7, _record), erlang:element(8, _record), erlang:element(9, _record), erlang:element(10, _record), erlang:element(11, _record), erlang:element(12, _record)} end, erlang:element(3, St), erlang:element(4, St)}. -file("src/pig/agent/state.gleam", 132). ?DOC(" Add a message to the end of history. Returns new state.\n"). -spec add_message(agent_state(), pig_protocol@message:message()) -> agent_state(). add_message(State, Msg) -> {agent_state, erlang:element(2, State), lists:append(erlang:element(3, State), [Msg]), erlang:element(4, State)}. -file("src/pig/agent/state.gleam", 137). ?DOC(" Get the conversation history in order.\n"). -spec history(agent_state()) -> list(pig_protocol@message:message()). history(State) -> erlang:element(3, State). -file("src/pig/agent/state.gleam", 142). ?DOC(" Increment the iteration counter. Returns new state.\n"). -spec increment_iterations(agent_state()) -> agent_state(). increment_iterations(State) -> {agent_state, erlang:element(2, State), erlang:element(3, State), erlang:element(4, State) + 1}. -file("src/pig/agent/state.gleam", 147). ?DOC(" Check if the agent has exceeded its maximum iterations.\n"). -spec exceeded_max_iterations(agent_state()) -> boolean(). exceeded_max_iterations(State) -> erlang:element(4, State) >= erlang:element(5, erlang:element(2, State)). -file("src/pig/agent/state.gleam", 152). ?DOC(" Get tool definitions from the registry.\n"). -spec tool_definitions(agent_state()) -> list(pig_protocol@tool_definition:tool_definition()). tool_definitions(State) -> pig@tool:list_definitions(erlang:element(3, erlang:element(2, State))). -file("src/pig/agent/state.gleam", 159). ?DOC( " Get messages for a provider call.\n" "\n" " Prepends the system prompt as a `System` message if one is configured.\n" ). -spec messages_for_provider(agent_state()) -> list(pig_protocol@message:message()). messages_for_provider(State) -> case erlang:element(4, erlang:element(2, State)) of {some, Prompt} -> [{system, Prompt} | erlang:element(3, State)]; none -> erlang:element(3, State) end. -file("src/pig/agent/state.gleam", 167). ?DOC(" Build an `AiError` for exceeding max iterations.\n"). -spec max_iterations_error(agent_state()) -> pig_protocol@error:ai_error(). max_iterations_error(State) -> {api_error, <<<<"Agent exceeded maximum iterations ("/utf8, (erlang:integer_to_binary( erlang:element(5, erlang:element(2, State)) ))/binary>>/binary, ")"/utf8>>}.