Packages

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

Current section

Files

Jump to
pig src pig@agent@state.erl
Raw

src/pig@agent@state.erl

-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>>}.