matrx-software / matrx

Human-Agent Teaming Rapid Experimentation Software
https://www.matrx-software.com
MIT License
10 stars 3 forks source link

Default AgentBrain leads to API error: `TypeError: Object of type State is not JSON serializable` #298

Closed thaije closed 3 years ago

thaije commented 3 years ago

Describe the bug For some reason the new State object is not fully converted to a regular dict before the API tries to json serialize it, which in turn fails and throws the error (see stacktrace).

The weird thing is that converting the state to dict and reordering it is the first thing being done in the API when receiving an agent state, see here: https://github.com/matrx-software/matrx/blob/master/matrx/api/api.py#L970. Checking the type of the state here also confirms this works, however checking it for the human agent view of the vis_test case shows it as an State object again here.

To Reproduce Running the vis_test case, pressing play, and checking the human agent view gives the following error: TypeError: Object of type State is not JSON serializable on this line in the API https://github.com/matrx-software/matrx/blob/dev/matrx/api/api.py#L141. It also happens for the run_test case when opening the human agent view. However, it does not seem to happen for:

Expected behavior No error and the state being converted to a dict in the API before it being sent to the frontend.

Stacktrace

TypeError: Object of type State is not JSON serializable
[2021-05-16 23:55:18,755] ERROR in app: Exception on /get_latest_state_and_messages [POST]
Traceback (most recent call last):
  File "/home/hal/.virtualenvs/matrx/lib/python3.8/site-packages/flask/app.py", line 2051, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/hal/.virtualenvs/matrx/lib/python3.8/site-packages/flask/app.py", line 1501, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/hal/.virtualenvs/matrx/lib/python3.8/site-packages/flask_cors/extension.py", line 165, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/home/hal/.virtualenvs/matrx/lib/python3.8/site-packages/flask/app.py", line 1499, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/hal/.virtualenvs/matrx/lib/python3.8/site-packages/flask/app.py", line 1485, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/home/hal/Projects/matrx/matrx/api/api.py", line 141, in get_latest_state_and_messages
    return jsonify({"matrx_paused": matrx_paused, "states": states_, "chatrooms": chatrooms, "messages": messages})
  File "/home/hal/.virtualenvs/matrx/lib/python3.8/site-packages/flask/json/__init__.py", line 348, in jsonify
    f"{dumps(data, indent=indent, separators=separators)}\n",
  File "/home/hal/.virtualenvs/matrx/lib/python3.8/site-packages/flask/json/__init__.py", line 129, in dumps
    rv = _json.dumps(obj, **kwargs)
  File "/usr/lib/python3.8/json/__init__.py", line 234, in dumps
    return cls(
  File "/usr/lib/python3.8/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python3.8/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/home/hal/.virtualenvs/matrx/lib/python3.8/site-packages/flask/json/__init__.py", line 56, in default
    return super().default(o)
  File "/usr/lib/python3.8/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '

Additional context Most likely a bug from fixing https://github.com/matrx-software/matrx/issues/202.

thaije commented 3 years ago

I added a temp fix that double checks that the state in the api is a dict: https://github.com/matrx-software/matrx/commit/f5d1102cff34baa9de93d241653871eb219951c6 which I'll include with the new release.

jwaa commented 3 years ago

@thaije I thought I had them all... There was an issue where the dictionary that State builds upon was also a State object. Which causes this issue. I thought I solved it, but perhaps I forgot something.

If this is the case, the State.to_dict() will just return the thing State uses at its core, which will be just be another State instead of a dict. Causing the fix to fail just like when it was used when a State is added in the api.

For which type of agent does it happen and when (e.g., all the time or only when the agent perfoms an action)?

I might be able to look at it tonight.

thaije commented 3 years ago

It seems to occur only with the default human agentbrain (but not in Bw4T), and just opening the human agent view gives the error.

jwaa commented 3 years ago

The error was cases because HumanAgentBrain did not use State.state_update(state_dict) appropriately (it passed a State instance as state_dict instead of an actual dict). Fixed that and now State.state_update throws an exception if it receives anything else then a dict. If it receives a State instance it will also suggest a fix: state.state_update(old_state.as_dict()).