opensistemas-hub / osbrain

osBrain - A general-purpose multi-agent system module written in Python
https://osbrain.readthedocs.io/en/stable/
Apache License 2.0
175 stars 43 forks source link

queries regarding osbrain agents #327

Closed brownbytes closed 5 years ago

brownbytes commented 5 years ago

Hi, I have few questions about the agents themselves.

  1. Are osbrain agents learning agents? While non of the examples provided address this - osmarkets website states osbrain agents as learning agents? https://osmarkets.net/platform/

  2. What is the agent architecture? For instance Jade agents are BDI agents. I am wondering what agent architecture is used to build osbrain agents?

  3. I tried running a asyncio server on one of the agents and I was hit with pickle error. I might have implemented the server incorrectly, but I was wondering if its actually possible?

    File "/usr/lib/python3.6/pickle.py", line 496, in save rv = reduce(self.proto) TypeError: can't pickle select.epoll objects

Peque commented 5 years ago

Hi @brownbytes,

  1. osBrain only provides a tool for implementing general-purpose multi-agent systems, but does not include any learning algorithms implemented by default. There are lots of learning algorithms (and toolboxes) so we think it would be out of scope for this tool. Good thing about osBrain is that it is implemented in Python, so it should integrate very easily with most currently-widely-used learning algorithms/toolboxes.
  2. For what I know, JADE does not constrain itself to BDI agents. There are layers that implement BDI agents on top on JADE though. Just like JADE, osBrain is a middleware which facilitates the development of multi-agent systems. How they behave is up to you.
  3. Can you share a reduced, complete and reproducible test case? Depending on which type of objects you are dealing with you might want to change the default serialization format.
brownbytes commented 5 years ago

Hi Peque,

Thanks for your reply. I have a functional asyncio based server . There are few different ways that I tried to run the server as an agent. First, the server program was intact with a event loop created in the server module (Charlie ). Though this approach did not throw errors, the server tasks doesnot get called.

import time
from osbrain import run_agent
from osbrain import run_nameserver
from Aliceagent import Greeter
from Bobagent import Bob
from Charlieagent import Charlie

def main():
    ns = run_nameserver()
    alice = run_agent('Alice', base=Greeter)
    bob = run_agent('Bob', base=Bob)
    charlie = run_agent('Charlie', base=Charlie)

    bob.connect(alice.addr('main'), handler='custom_log')

    for _ in range(3):
        alice.hello('Bob')
        time.sleep(1)

if __name__ == '__main__':
    main()
    #ns.shutdown()
#agent 1
from osbrain import Agent
import asyncio

class Charlie(Agent):
    def on_init(self):
        self.loop = asyncio.get_event_loop()
        self.run1()

    def run1(self):
        self.loop.create_task(self.server())
        print("creating a task for the server")

    async def server(self):
        print("in server")
        ### followed by other asycn-await methods

I dont see task created for server running. Second: I tried creating a event loop in the namespace agent and passed it to the server agent

import time
from osbrain import run_agent
from osbrain import run_nameserver
from Aliceagent import Greeter
from Bobagent import Bob
from Charlieagent import Charlie
import asyncio

def main():
    loop = asyncio.get_event_loop()
    ns = run_nameserver()
    alice = run_agent('Alice', base=Greeter)
    bob = run_agent('Bob', base=Bob)
    charlie = run_agent('Charlie', base=Charlie)
    charlie.run1(loop)
    bob.connect(alice.addr('main'), handler='custom_log')

    for _ in range(3):
        alice.hello('Bob')
        time.sleep(1)

if __name__ == '__main__':
    main()
    #ns.shutdown()
#agent 1
from osbrain import Agent
import asyncio

class Charlie(Agent):
    def on_init(self):
        #self.loop = asyncio.get_event_loop()
        #self.run1(loop)
        pass

    def run1(self,loop):
        loop.create_task(self.server())
        print("creating a task for the server")

    async def server(self):
        print("in server")
        ### followed by other asycn-await methods

This throws an error

...
1, (<Handle BaseSelectorEventLoop._read_from_self()>, None))), 139821787513960: (112, SelectorKey(fileobj=4, fd=4, events=1, data=(<Handle BaseSelectorEventLoop._read_from_self()>, None))), 139821868557848: (113, '_map'), 139821868553536: (114, '_SelectorMapping'), 43969736: (115, <class 'selectors._SelectorMapping'>), 139821792889544: (116, <selectors._SelectorMapping object at 0x7f2acc4c0ac8>), 139821792936080: (117, {'_selector': <selectors.EpollSelector object at 0x7f2ad0e81f98>}), 139821868560312: (118, '_epoll')}
        self.proto = 4
        self.bin = True
        self.fast = 0
        self.fix_imports = False
        self.globals_ref = {139821787394696: {'__package__': 'asyncio', '__name__': 'asyncio.selector_events', '__file__': '/usr/lib/python3.6/asyncio/selector_events.py'}}
    t = <class 'select.epoll'>
    x = None
----------------------------------------------------
 EXCEPTION <class 'TypeError'>: can't pickle select.epoll objects
----------------------------------------------------

I am unsure of the way in which I can run a server as a an agent?

Peque commented 5 years ago

@brownbytes Yeah, for what I can see you should go with the first implementation. The second would not work because you cannot serialize everything (in this case an event poll it seems).

About the first code: it seems you are not running the asyncio event loop and that is why the method is not being executed.

osBrain uses its own ZeroMQ event loop, and by creating your own asyncio event loop you should not assume it will be automatically executed. That means you should call .run_forever() somewhere (or whichever method you want to use to run the asyncio tasks).

Normally, you do not want to run that loop in a way that blocks the ZeroMQ loop, so you may want to have a look at osBrain timers or advanced proxy handling.

Anyway, do you really need the asyncio loop? Is there anything you cannot do with the current ZeroMQ-based event loop?

brownbytes commented 5 years ago

"About the first code: it seems you are not running the asyncio event loop and that is why the method is not being executed." Thanks for the heads-up. I overlooked it while I experimenting. run_forever() successfully starts the server. I dont intend to run another event loop using asycnio alongside the event loop that osBrain uses . As i had mentioned earlier, external clients( not agents) connect to the asynchronous server. I am trying to attach more applications to this server as agents which will use the underlying ZeroMQ loop.

Thanks again.

Peque commented 5 years ago

@brownbytes Closing this issue then. :blush:

Feel free to open a new one if you find any other problem or difficulty with osBrain.