示例#1
0
        public Task <AgentContext <MemberState> > Run(object state, AgentCapability self, object message)
        {
            var agentState = state as MemberState ?? new MemberState();
            var context    = new AgentContext <MemberState>(agentState, self);

            switch (message)
            {
            case InitWetonomyAgentMessage initMsg:
                //context.SubscribeUserInput()
                var distributeCapabilityMessage = new DistributeCapabilitiesMessage
                {
                    Id = self.Issuer,
                    AgentCapabilities = new Dictionary <string, AgentCapability>()
                    {
                        { "AddGroupMessage", context.IssueCapability(new[] { typeof(AddGroupMessage) }) },
                        { "RemoveMemberMessage", context.IssueCapability(new[] { typeof(RemoveMemberMessage) }) },
                    }
                };

                context.SendMessage(initMsg.CreatorAgentCapability, distributeCapabilityMessage, null);
                break;

            case AddGroupMessage addGroupMessage:
                context.State.Groups.Add(addGroupMessage.GroupAgentId);
                break;

            case RemoveMemberMessage removeGroupMessage:
                context.State.Groups.Remove(removeGroupMessage.GroupAgentId);
                break;
            }

            return(Task.FromResult(context));
        }
示例#2
0
        public Task <AgentContext <object> > Run(object state, AgentCapability self, object message)
        {
            var context = new AgentContext <object>(state, self);

            if (message is PingPongMessage initMessage && initMessage.AgentTwo == null)
            {
                var cap = context.IssueCapability(new[] { typeof(PingPongMessage) });
                context.SendMessage(initMessage.AgentOne, new PingPongMessage
                {
                    AgentOne = initMessage.AgentOne,
                    AgentTwo = cap
                }, null);
            }
示例#3
0
        public Task <AgentContext <object> > Run(object state, AgentCapability self, object message)
        {
            var context = new AgentContext <object>(state, self);

            if (message is AgentRootInitMessage rootInitMessage)
            {
                var cap = context.IssueCapability(new[] { typeof(PingPongMessage) });
                context.CreateAgent("AgentTwoId", "AgentTwo", new PingPongMessage {
                    AgentOne = cap
                }, null);
            }
            else if (message is PingPongMessage pingPongMessage)
            {
                context.SendMessage(pingPongMessage.AgentTwo, new PingPongMessage
                {
                    AgentOne = pingPongMessage.AgentOne,
                    AgentTwo = pingPongMessage.AgentTwo,
                    Content  = "Ping"
                }, null);
            }
            return(Task.FromResult(context));
        }
        public Task <AgentContext <OrganizationState> > Run(object state, AgentCapability self, object message)
        {
            var organizationState    = state as OrganizationState ?? new OrganizationState();
            var context              = new AgentContext <OrganizationState>(organizationState, self);
            var distributeCapability = context.IssueCapability(new[] { typeof(DistributeCapabilitiesMessage) });

            switch (message)
            {
            case AgentRootInitMessage _:

                var memberFactoryInitMessage = new InitWetonomyAgentMessage(distributeCapability);
                context.CreateAgent("memberAndGroupFactory", "MemberAndGroupFactoryAgent", memberFactoryInitMessage, null);
                break;

            case DistributeCapabilitiesMessage DistributeCapabilitiesMessage:
                context.State.AgentToCapabilities.Add(DistributeCapabilitiesMessage.Id, DistributeCapabilitiesMessage.AgentCapabilities);

                switch (DistributeCapabilitiesMessage.Id)
                {
                // -------- Members, Groups & Voting --------
                case "memberAndGroupFactory":
                    //var createFirstMemberMsg = new CreateGroupMessage("FirstGroup");
                    //var creatGroupMessage = DistributeCapabilitiesMessage.AgentCapabilities["MintTokenMessage"];
                    //context.SendMessage(creatGroupMessage, createFirstMemberMsg, null);

                    var creatMemberCap = DistributeCapabilitiesMessage.AgentCapabilities["CreateMemberMessage"];
                    for (int i = 0; i < 5; i++)
                    {
                        var createMemberMsg = new CreateMemberMessage("MemberDebt" + i);
                        context.SendMessage(creatMemberCap, createMemberMsg, null);
                    }


                    var votingInitMessage = new InitWetonomyAgentMessage(distributeCapability);
                    context.CreateAgent("centralVoting", "VotingAgent", votingInitMessage, null);
                    break;

                case "centralVoting":
                    //var votingInitMessage = new InitWetonomyAgentMessage(distributeCapability);
                    //context.CreateAgent("centralVoting", "VotingAgent", votingInitMessage, null);
                    var moneyTokenManagerInitMessage = new InitWetonomyAgentMessage(distributeCapability);
                    context.CreateAgent("moneyTokenManager", "TokenManagerAgent", moneyTokenManagerInitMessage, null);
                    break;

                // -------- Token Flow --------

                case "moneyTokenManager":
                    var mintCapability   = DistributeCapabilitiesMessage.AgentCapabilities["MintTokenMessage"];
                    var moneyTokenMinter = new TokenActionAgentInitMessage(
                        mintCapability,
                        distributeCapability,
                        new Dictionary <AgentTriggerPair, ITriggeredAction>(),
                        null,
                        new HashSet <string>()
                    {
                        "debtTokenBurner", "allowanceTokenBurner"
                    });
                    context.CreateAgent("moneyTokenMinter", "TokenMinterAgent", moneyTokenMinter, null);
                    break;

                case "moneyTokenMinter":

                    var cashTokenManagerInitMessage      = new InitWetonomyAgentMessage(distributeCapability);
                    var debtTokenManagerInitMessage      = new InitWetonomyAgentMessage(distributeCapability);
                    var allowanceTokenManagerInitMessage = new InitWetonomyAgentMessage(distributeCapability);

                    context.CreateAgent("cashTokenManager", "TokenManagerAgent", cashTokenManagerInitMessage, null);
                    context.CreateAgent("debtTokenManager", "TokenManagerAgent", debtTokenManagerInitMessage, null);
                    context.CreateAgent("allowanceTokenManager", "TokenManagerAgent", allowanceTokenManagerInitMessage, null);
                    break;

                case "cashTokenManager":
                    var splitCapability    = DistributeCapabilitiesMessage.AgentCapabilities["TransferTokenMessage"];
                    var tokenSplitterAgent = new TokenActionAgentInitMessage(
                        splitCapability,
                        distributeCapability,
                        new Dictionary <AgentTriggerPair, ITriggeredAction>()
                    {
                        { new AgentTriggerPair("cashTokenManager", typeof(TokensTransferedNotification)), new UniformSplitterStrategy() }
                    },
                        new List <IAgentTokenKey>()
                    {
                        new SingleAngentTokenKey("cashTokenBurnerForDebt"), new SingleAngentTokenKey("cashTokenBurnerForAllowance")
                    });
                    context.CreateAgent("cashTokenSplitter", "TokenSplitterAgent", tokenSplitterAgent, null);


                    var burnCapability         = DistributeCapabilitiesMessage.AgentCapabilities["BurnTokenMessage"];
                    var cashTokenBurnerForDebt = new TokenActionAgentInitMessage(
                        burnCapability,
                        distributeCapability,
                        new Dictionary <AgentTriggerPair, ITriggeredAction>()
                    {
                        { new AgentTriggerPair("cashTokenManager", typeof(TokensTransferedNotification)), new SelfBurnStrategy() }
                    });
                    context.CreateAgent("cashTokenBurnerForDebt", "TokenBurnerAgent", cashTokenBurnerForDebt, null);


                    var cashTokenBurnerForAllowance = new TokenActionAgentInitMessage(
                        burnCapability,
                        distributeCapability,
                        new Dictionary <AgentTriggerPair, ITriggeredAction>()
                    {
                        { new AgentTriggerPair("cashTokenManager", typeof(TokensTransferedNotification)), new SelfBurnStrategy() }
                    });
                    context.CreateAgent("cashTokenBurnerForAllowance", "TokenBurnerAgent", cashTokenBurnerForAllowance, null);
                    break;

                case "debtTokenManager":
                    var debtBurnCapability = DistributeCapabilitiesMessage.AgentCapabilities["BurnTokenMessage"];
                    var debtTokenBurner    = new TokenActionAgentInitMessage(
                        debtBurnCapability,
                        distributeCapability,
                        new Dictionary <AgentTriggerPair, ITriggeredAction>()
                    {
                        { new AgentTriggerPair("cashTokenBurnerForDebt", typeof(TokensBurnedTriggerer)), new SequentialBurnStrategy() }
                    },
                        null,
                        new HashSet <string>()
                    {
                        "cashTokenBurnerForDebt", "debtTokenMinter"
                    });
                    context.CreateAgent("debtTokenBurner", "TokenBurnerAgent", debtTokenBurner, null);

                    var debtMintCapability = DistributeCapabilitiesMessage.AgentCapabilities["MintTokenMessage"];
                    var debtTokenMinter    = new TokenActionAgentInitMessage(
                        debtMintCapability,
                        distributeCapability,
                        new Dictionary <AgentTriggerPair, ITriggeredAction>()
                    {
                        { new AgentTriggerPair("AgentRoot", typeof(MockMessageTrigger)), new MintForAgentOnBurnerStrategy() }
                    });
                    context.CreateAgent("debtTokenMinter", "TokenMinterAgent", debtTokenMinter, null);
                    break;

                case "allowanceTokenManager":

                    //Should add minter
                    var allowanceBurnCapability = DistributeCapabilitiesMessage.AgentCapabilities["BurnTokenMessage"];
                    var allowanceTokenBurner    = new TokenActionAgentInitMessage(
                        allowanceBurnCapability,
                        distributeCapability,
                        new Dictionary <AgentTriggerPair, ITriggeredAction>()
                    {
                        //{ new AgentTriggerPair("cashTokenBurnerForAllowance" ,typeof(TokensBurnedTriggerer)), new SequentialBurnStrategy()}
                    },
                        null,
                        new HashSet <string>()
                    {
                        "cashTokenBurnerForAllowance"
                    });
                    context.CreateAgent("allowanceTokenBurner", "TokenBurnerAgent", allowanceTokenBurner, null);
                    break;

                case "debtTokenMinter":
                    var debtTokenMinterCapability = new AgentCapability("debtTokenMinter", typeof(MockMessageTrigger));

                    for (int i = 0; i < 5; i++)
                    {
                        var mintTokenMessage = new MockMessageTrigger("AgentRoot", 100, new SingleAngentTokenKey("MemberDebt" + i));
                        context.SendMessage(debtTokenMinterCapability, mintTokenMessage, null);
                    }
                    break;

                case "debtTokenBurner":

                    var cap1            = context.State.AgentToCapabilities["moneyTokenMinter"]["AddTriggerToActionMessage"];
                    var debtBurnTrigger = new AddTriggerToActionMessage(new AgentTriggerPair("debtTokenBurner", typeof(TokensBurnedTriggerer)), new SingleMintAfterBurnStrategy());
                    context.SendMessage(cap1, debtBurnTrigger, null);
                    break;

                case "allowanceTokenBurner":

                    var cap2 = context.State.AgentToCapabilities["moneyTokenMinter"]["AddTriggerToActionMessage"];
                    var allowanceBurnTrigger = new AddTriggerToActionMessage(new AgentTriggerPair("allowanceTokenBurner", typeof(TokensBurnedTriggerer)), new SingleMintAfterBurnStrategy());
                    context.SendMessage(cap2, allowanceBurnTrigger, null);

                    // Imitate user action
                    var mintSingleKey = new SingleAngentTokenKey(self.Issuer);
                    context.AddReminder(TimeSpan.FromSeconds(5), new MintTokenMessage(100, mintSingleKey));
                    break;
                }
                break;

            // Imitate user action
            case MintTokenMessage mintCashToken:
                var cashTokenManager = context.State.AgentToCapabilities["cashTokenManager"]["MintTokenMessage"];
                context.SendMessage(cashTokenManager, mintCashToken, null);
                break;

            case TokensMintedNotification tokensMintedNotification:
                var transferCashTokenManager = context.State.AgentToCapabilities["cashTokenManager"]["TransferTokenMessage"];
                context.SendMessage(transferCashTokenManager, new TransferTokenMessage(100, new SingleAngentTokenKey(self.Issuer), new SingleAngentTokenKey("cashTokenSplitter")), null);
                break;
            }
            return(Task.FromResult(context));
        }
示例#5
0
        public Task <AgentContext <VotingState> > Run(object state, AgentCapability self, object message)
        {
            var context = new AgentContext <VotingState>(state as VotingState, self);

            switch (message)
            {
            case InitWetonomyAgentMessage initMsg:
                var distributeCapabilityMessage = new DistributeCapabilitiesMessage
                {
                    Id = self.Issuer,
                    AgentCapabilities = new Dictionary <string, AgentCapability>()
                    {
                        { "AddVoteMessage", context.IssueCapability(new[] { typeof(AddVoteMessage <T>) }) },
                        { "AddDecisionMessage", context.IssueCapability(new[] { typeof(AddDecisionMessage) }) },
                        //{"ForwardMessage", context.IssueCapability(new[]{ typeof(ForwardMessage) })}
                    }
                };
                context.SendMessage(initMsg.CreatorAgentCapability, distributeCapabilityMessage, null);
                break;

            case AddVoteMessage <V> addVoteMessage:
                context.State.DecisionsVotes[addVoteMessage.DecisionId].Add(addVoteMessage.Sender, addVoteMessage.Vote);
                context.MakePublication(new NewVotePublication <V>(addVoteMessage.DecisionId, addVoteMessage.Vote));
                break;

            case AddDecisionMessage addDecisionMessage:
                var decision = new Decision <T>(
                    context.State.nonce.ToString(),
                    addDecisionMessage.Executable,
                    addDecisionMessage.ActionMessage,
                    addDecisionMessage.Start,
                    addDecisionMessage.Finale);

                context.State.Decisions.Add(context.State.nonce.ToString(), decision);
                context.State.DecisionsVotes.Add(context.State.nonce.ToString(), new Dictionary <string, V>());

                context.MakePublication(
                    new NewDecisionPublication(context.State.nonce.ToString(), addDecisionMessage.ActionMessage)
                    );

                context.AddReminder(decision.Finale - DateTime.Now, new FinalizeDecision(context.State.nonce.ToString()));
                //Just Temporary solution
                context.State.nonce++;
                break;

            case FinalizeDecision finalizeDecisionMessage:
                var             dec   = context.State.Decisions[finalizeDecisionMessage.DecisionId];
                IEnumerable <V> votes =
                    context.State.DecisionsVotes[finalizeDecisionMessage.DecisionId]
                    .Select(pair => pair.Value);

                T decisionEvaluation = context.State.VotingStategy.MakeDecision(votes);

                dec.Evaluation = decisionEvaluation;
                dec.State      = DecisionState.Finalized;


                if (dec.Executable)
                {
                    //Executes only if T is bool, not sure if we need execution when T isn't bool
                    if (decisionEvaluation is bool check && check)
                    {
                        // should discuss how we store Capabilities
                        context.ForwardMessage(null, dec.DecisionActionMessage, null);
                    }
                }
                break;
            }

            return(Task.FromResult(context));
        }
示例#6
0
        public Task <AgentContext <RecipientState> > Run(object state, AgentCapability self, object message)
        {
            var agentState = state as RecipientState ?? new RecipientState();
            var context    = new AgentContext <RecipientState>(agentState, self);

            if (message is AbstractTrigger msg)
            {
                var pair = new AgentTriggerPair(msg.Sender, message.GetType());
                if (context.State.TriggerToAction.ContainsKey(pair))
                {
                    (IList <object>, IList <object>)result = RecipientState.TriggerCheck(context.State, pair, msg);

                    foreach (var action in result.Item1)
                    {
                        context.SendMessage(context.State.TokenManagerAgent, action, null);
                    }

                    foreach (var publication in result.Item2)
                    {
                        context.MakePublication(publication);
                    }

                    return(Task.FromResult(context));
                }
            }

            switch (message)
            {
            case TokenActionAgentInitMessage initMessage:
                context.State.TokenManagerAgent = initMessage.TokenManagerAgentCapability;
                context.State.TriggerToAction   = initMessage.TriggererToAction ?? new Dictionary <AgentTriggerPair, ITriggeredAction>();
                context.State.Recipients        = initMessage.Recipients;// ?? new List<IAgentTokenKey>();
                context.State.SelfId            = self.Issuer;

                var distributeCapabilityMessage = new DistributeCapabilitiesMessage
                {
                    Id = self.Issuer,
                    AgentCapabilities = new Dictionary <string, AgentCapability>()
                    {
                        { "AddRecipientMessage", context.IssueCapability(new[] { typeof(AddRecipientMessage) }) },
                        { "RemoveRecipientMessage", context.IssueCapability(new[] { typeof(RemoveRecipientMessage) }) },
                        { "AddTriggerToActionMessage", context.IssueCapability(new[] { typeof(AddTriggerToActionMessage) }) },
                    }
                };
                if (initMessage.Subscription != null)
                {
                    foreach (var agent in initMessage.Subscription)
                    {
                        context.AddSubscription(agent);
                    }
                }
                context.SendMessage(initMessage.CreatorAgentCapability, distributeCapabilityMessage, null);
                break;

            case AddRecipientMessage addMessage:
                if (context.State.AddRecipient(addMessage.Recipient))
                {
                    context.MakePublication(new RecipientAddedPublication(addMessage.Recipient));
                }
                break;

            case RemoveRecipientMessage removeMessage:
                if (context.State.RemoveRecipient(removeMessage.Recipient))
                {
                    context.MakePublication(new RecipientRemovedPublication(removeMessage.Recipient));
                }
                break;

            case AddTriggerToActionMessage addTriggerMessage:
                context.State.TriggerToAction.Add(addTriggerMessage.Trigger, addTriggerMessage.Action);
                break;
            }

            return(Task.FromResult(context));
        }
示例#7
0
        public Task <AgentContext <TokenBurnerState> > Run(object state, AgentCapability self, object message)
        {
            var agentState = state as TokenBurnerState ?? new TokenBurnerState();
            var context    = new AgentContext <TokenBurnerState>(agentState, self);

            if (message is AbstractTrigger msg)
            {
                var pair = new AgentTriggerPair(msg.Sender, message.GetType());
                if (context.State.TriggerToAction.ContainsKey(pair))
                {
                    (IList <object>, IList <object>)result = RecipientState.TriggerCheck(context.State, pair, msg);

                    foreach (BurnTokenMessage action in result.Item1)
                    {
                        context.SendMessage(context.State.TokenManagerAgent, action, null);
                    }

                    foreach (var publication in result.Item2)
                    {
                        context.MakePublication(publication);
                    }

                    return(Task.FromResult(context));
                }
            }

            switch (message)
            {
            case TokenActionAgentInitMessage initMessage:
                context.State.TokenManagerAgent = initMessage.TokenManagerAgentCapability;
                context.State.TriggerToAction   = initMessage.TriggererToAction ?? new Dictionary <AgentTriggerPair, ITriggeredAction>();
                context.State.SelfId            = self.Issuer;

                var distributeCapabilityMessage = new DistributeCapabilitiesMessage
                {
                    Id = self.Issuer,
                    AgentCapabilities = new Dictionary <string, AgentCapability>()
                    {
                        { "GetTokensMessage", context.IssueCapability(new[] { typeof(GetTokensMessage) }) },
                        { "AddTriggerToActionMessage", context.IssueCapability(new[] { typeof(AddTriggerToActionMessage) }) },
                    }
                };
                if (initMessage.Subscription != null)
                {
                    foreach (var agent in initMessage.Subscription)
                    {
                        context.AddSubscription(agent);
                    }
                }
                context.SendMessage(initMessage.CreatorAgentCapability, distributeCapabilityMessage, null);
                break;

            //Tokens are minted on burner's addres so that he can burn them,
            //but they are actually for the user TokensMintedTriggerer.To
            //He is added as recipient and he can take ownership of the tokens with GetTokensMessage
            //This is done so that the system can work automaticly
            case TokensMintedTriggerer transferedMessage:
                if (context.State.AddRecipient(transferedMessage.To))
                {
                    context.State.MintedMessages.Add(transferedMessage);
                    context.MakePublication(new RecipientAddedPublication(transferedMessage.To));
                }
                break;

            case GetTokensMessage getTokensMessage:
                IAgentTokenKey agentSender;
                if (context.State.GetTokens(getTokensMessage.Recipient, getTokensMessage.Amount, out agentSender))
                {
                    var transfer = new TransferTokenMessage(getTokensMessage.Amount, agentSender, getTokensMessage.Recipient);
                    context.SendMessage(null, transfer, null);
                }
                break;

            case AddTriggerToActionMessage addTriggerMessage:
                context.State.TriggerToAction.Add(addTriggerMessage.Trigger, addTriggerMessage.Action);
                break;
            }

            return(Task.FromResult(context));
        }
        public Task <AgentContext <TokenManagerState> > Run(object state, AgentCapability self, object message)
        {
            var agentState = state as TokenManagerState ?? new TokenManagerState();
            var context    = new AgentContext <TokenManagerState>(agentState, self);

            switch (message)
            {
            case InitWetonomyAgentMessage tokenManagerInitMessage:
                var distributeCapabilityMessage = new DistributeCapabilitiesMessage
                {
                    Id = self.Issuer,
                    AgentCapabilities = new Dictionary <string, AgentCapability>()
                    {
                        { "BurnTokenMessage", context.IssueCapability(new[] { typeof(BurnTokenMessage) }) },
                        { "MintTokenMessage", context.IssueCapability(new[] { typeof(MintTokenMessage) }) },
                        { "TransferTokenMessage", context.IssueCapability(new[] { typeof(TransferTokenMessage) }) },
                    }
                };

                context.SendMessage(tokenManagerInitMessage.CreatorAgentCapability, distributeCapabilityMessage, null);
                break;

            case BurnTokenMessage burnTokenMessage:
                if (context.State.Burn(burnTokenMessage.Amount, burnTokenMessage.From))
                {
                    var notificationCapability = new AgentCapability(burnTokenMessage.From.GetAgentId(), typeof(TokensMintedNotification));

                    context.SendMessage(notificationCapability, new TokensBurnedNotification(self.Issuer, burnTokenMessage.Amount, burnTokenMessage.From), null);

                    context.MakePublication(
                        new TokenBurnPublication(burnTokenMessage.Amount, burnTokenMessage.From)
                        );
                }
                break;

            case MintTokenMessage mintTokenMessage:

                if (context.State.Mint(mintTokenMessage.Amount, mintTokenMessage.To))
                {
                    var notificationCapability = new AgentCapability(mintTokenMessage.To.GetAgentId(), typeof(TokensMintedNotification));

                    context.SendMessage(notificationCapability, new TokensMintedNotification(self.Issuer, mintTokenMessage.Amount, mintTokenMessage.To), null);

                    context.MakePublication(
                        new TokenMintPublication(mintTokenMessage.Amount, mintTokenMessage.To)
                        );
                }
                break;

            case TransferTokenMessage transferTokenMessage:
                if (context.State.Transfer(transferTokenMessage.Amount, transferTokenMessage.From, transferTokenMessage.To))
                {
                    var notificationCapabilityTo   = new AgentCapability(transferTokenMessage.To.GetAgentId(), typeof(TokensMintedNotification));
                    var notificationCapabilityFrom = new AgentCapability(transferTokenMessage.From.GetAgentId(), typeof(TokensMintedNotification));

                    context.SendMessage(notificationCapabilityTo, new TokensTransferedNotification(self.Issuer, transferTokenMessage.Amount, transferTokenMessage.From, transferTokenMessage.To), null);
                    context.SendMessage(notificationCapabilityFrom, new TokensTransferedNotification(self.Issuer, transferTokenMessage.Amount, transferTokenMessage.From, transferTokenMessage.To), null);

                    context.MakePublication(
                        new TokenTransferPublication(transferTokenMessage.Amount, transferTokenMessage.From, transferTokenMessage.To)
                        );
                }
                break;
            }
            return(Task.FromResult(context));
        }
示例#9
0
        public Task <AgentContext <FactoryState> > Run(object state, AgentCapability self, object message)
        {
            var agentState = state as FactoryState ?? new FactoryState();
            var context    = new AgentContext <FactoryState>(agentState, self);

            switch (message)
            {
            case InitWetonomyAgentMessage initMsg:
                var distributeCapabilityMessage = new DistributeCapabilitiesMessage
                {
                    Id = self.Issuer,
                    AgentCapabilities = new Dictionary <string, AgentCapability>()
                    {
                        { "CreateGroupMessage", context.IssueCapability(new[] { typeof(CreateGroupMessage) }) },
                        { "CreateMemberMessage", context.IssueCapability(new[] { typeof(CreateMemberMessage) }) },
                        { "RemoveRefMessage", context.IssueCapability(new[] { typeof(RemoveRefMessage) }) },
                        { "GetCapabilityMessage", context.IssueCapability(new[] { typeof(GetCapabilityMessage) }) },
                        { "ForwardMessage", context.IssueCapability(new[] { typeof(ForwardMessage) }) }
                    }
                };
                context.SendMessage(initMsg.CreatorAgentCapability, distributeCapabilityMessage, null);
                break;

            case CreateGroupMessage createGroupMsg:
                // should use created one
                var distribute = context.IssueCapability(new[] { typeof(DistributeCapabilitiesMessage) });
                context.CreateAgent(createGroupMsg.Id, "GroupAgent", distribute, null);
                break;

            case CreateMemberMessage createMemberMessage:
                // should use created one
                var distribute2 = context.IssueCapability(new[] { typeof(DistributeCapabilitiesMessage) });
                context.CreateAgent(createMemberMessage.Id, "MemberAgent", distribute2, null);
                break;

            case RemoveRefMessage removeMemberMessage:
                context.State.AgentToCapabilities.Remove(removeMemberMessage.Id);
                break;

            // for forwarding
            case GetCapabilityMessage getCapabilitiesMessage:
                var capability = context.IssueCapability(new[] { getCapabilitiesMessage.CapabilityType });
                var distributeCapabilityMsg = new DistributeCapabilitiesMessage
                {
                    Id = getCapabilitiesMessage.Sender,
                    AgentCapabilities = new Dictionary <string, AgentCapability>()
                    {
                        { getCapabilitiesMessage.CapabilityType.Name, capability },
                    }
                };
                //check if Type.Name works as expected
                context.SendMessage(null, distributeCapabilityMsg, null);
                break;

            case DistributeCapabilitiesMessage distributeCapabilitiesMsg:
                context.State.AgentToCapabilities.Add(distributeCapabilitiesMsg.Id, distributeCapabilitiesMsg.AgentCapabilities);
                break;

            default:
                Task <AgentContext <BaseState> > secondaryContextTask = base.Run(agentState, self, message);
                var secondaryContext = secondaryContextTask.GetAwaiter().GetResult();
                context.MergeSecondaryContext(secondaryContext.GetCommands());
                break;
            }

            return(Task.FromResult(context));
        }