Packages

Advanced Self-Optimizing Distributed Multi-Agent System with Quantum Coordination

Current section

Files

Jump to
agents src agent_collaboration.erl
Raw

src/agent_collaboration.erl

%% agent_collaboration.erl
%% Module for managing agent collaboration and communication
-module(agent_collaboration).
-behaviour(gen_server).
%% API
-export([
start_link/0,
create_collaboration/3,
send_message/3,
broadcast_to_group/2,
join_group/2,
leave_group/2,
get_collaborations/1,
get_group_members/1
]).
%% gen_server callbacks
-export([
init/1,
handle_call/3,
handle_cast/2,
handle_info/2,
terminate/2,
code_change/3
]).
-record(state, {
collaborations = #{} :: map(), % collaboration_id => #{agents, messages, created_at}
groups = #{} :: map(), % group_id => [agent_ids]
agent_groups = #{} :: map() % agent_id => [group_ids]
}).
-define(SERVER, ?MODULE).
%% API Functions
start_link() ->
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
create_collaboration(AgentId1, AgentId2, Purpose) ->
gen_server:call(?SERVER, {create_collaboration, AgentId1, AgentId2, Purpose}).
send_message(CollaborationId, FromAgent, Message) ->
gen_server:call(?SERVER, {send_message, CollaborationId, FromAgent, Message}).
broadcast_to_group(GroupId, Message) ->
gen_server:cast(?SERVER, {broadcast, GroupId, Message}).
join_group(AgentId, GroupId) ->
gen_server:call(?SERVER, {join_group, AgentId, GroupId}).
leave_group(AgentId, GroupId) ->
gen_server:call(?SERVER, {leave_group, AgentId, GroupId}).
get_collaborations(AgentId) ->
gen_server:call(?SERVER, {get_collaborations, AgentId}).
get_group_members(GroupId) ->
gen_server:call(?SERVER, {get_group_members, GroupId}).
%% gen_server callbacks
init([]) ->
{ok, #state{}}.
handle_call({create_collaboration, AgentId1, AgentId2, Purpose}, _From, State) ->
CollabId = generate_collaboration_id(),
Collaboration = #{
id => CollabId,
agents => [AgentId1, AgentId2],
purpose => Purpose,
messages => [],
created_at => erlang:timestamp(),
status => active
},
NewCollaborations = maps:put(CollabId, Collaboration, State#state.collaborations),
% Notify both agents
notify_agents([AgentId1, AgentId2], {collaboration_created, CollabId, Purpose}),
{reply, {ok, CollabId}, State#state{collaborations = NewCollaborations}};
handle_call({send_message, CollaborationId, FromAgent, Message}, _From, State) ->
case maps:get(CollaborationId, State#state.collaborations, undefined) of
undefined ->
{reply, {error, collaboration_not_found}, State};
Collaboration ->
% Check if agent is part of collaboration
case lists:member(FromAgent, maps:get(agents, Collaboration)) of
true ->
EnrichedMessage = #{
from => FromAgent,
content => Message,
timestamp => erlang:timestamp()
},
UpdatedMessages = [EnrichedMessage | maps:get(messages, Collaboration)],
UpdatedCollab = maps:put(messages, UpdatedMessages, Collaboration),
NewCollaborations = maps:put(CollaborationId, UpdatedCollab, State#state.collaborations),
% Notify other agents in collaboration
OtherAgents = lists:delete(FromAgent, maps:get(agents, Collaboration)),
notify_agents(OtherAgents, {collaboration_message, CollaborationId, EnrichedMessage}),
{reply, ok, State#state{collaborations = NewCollaborations}};
false ->
{reply, {error, agent_not_in_collaboration}, State}
end
end;
handle_call({join_group, AgentId, GroupId}, _From, State) ->
Groups = State#state.groups,
AgentGroups = State#state.agent_groups,
% Add agent to group
UpdatedGroup = case maps:get(GroupId, Groups, undefined) of
undefined -> [AgentId];
Members -> [AgentId | Members]
end,
% Update agent's group list
UpdatedAgentGroups = case maps:get(AgentId, AgentGroups, undefined) of
undefined -> [GroupId];
CurrentGroups -> [GroupId | CurrentGroups]
end,
NewState = State#state{
groups = maps:put(GroupId, UpdatedGroup, Groups),
agent_groups = maps:put(AgentId, UpdatedAgentGroups, AgentGroups)
},
% Notify group members
notify_agents(UpdatedGroup, {agent_joined_group, GroupId, AgentId}),
{reply, ok, NewState};
handle_call({leave_group, AgentId, GroupId}, _From, State) ->
Groups = State#state.groups,
AgentGroups = State#state.agent_groups,
% Remove agent from group
UpdatedGroup = case maps:get(GroupId, Groups, undefined) of
undefined -> [];
Members -> lists:delete(AgentId, Members)
end,
% Update agent's group list
UpdatedAgentGroups = case maps:get(AgentId, AgentGroups, undefined) of
undefined -> [];
CurrentGroups -> lists:delete(GroupId, CurrentGroups)
end,
NewState = State#state{
groups = maps:put(GroupId, UpdatedGroup, Groups),
agent_groups = maps:put(AgentId, UpdatedAgentGroups, AgentGroups)
},
% Notify remaining group members
notify_agents(UpdatedGroup, {agent_left_group, GroupId, AgentId}),
{reply, ok, NewState};
handle_call({get_collaborations, AgentId}, _From, State) ->
AgentCollabs = maps:fold(fun(CollabId, Collab, Acc) ->
case lists:member(AgentId, maps:get(agents, Collab)) of
true -> [CollabId | Acc];
false -> Acc
end
end, [], State#state.collaborations),
{reply, AgentCollabs, State};
handle_call({get_group_members, GroupId}, _From, State) ->
Members = maps:get(GroupId, State#state.groups, []),
{reply, Members, State};
handle_call(_Request, _From, State) ->
{reply, {error, unknown_request}, State}.
handle_cast({broadcast, GroupId, Message}, State) ->
case maps:get(GroupId, State#state.groups, undefined) of
undefined ->
{noreply, State};
Members ->
BroadcastMessage = #{
type => group_broadcast,
group_id => GroupId,
content => Message,
timestamp => erlang:timestamp()
},
notify_agents(Members, BroadcastMessage),
{noreply, State}
end;
handle_cast(_Msg, State) ->
{noreply, State}.
handle_info(_Info, State) ->
{noreply, State}.
terminate(_Reason, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%% Internal functions
generate_collaboration_id() ->
list_to_binary(uuid:uuid_to_string(uuid:get_v4())).
notify_agents(AgentIds, Message) ->
lists:foreach(fun(AgentId) ->
case agent_registry:find_agent(AgentId) of
{ok, Pid} ->
gen_server:cast(Pid, {collaboration_event, Message});
_ ->
ok
end
end, AgentIds).