>>37129
Aight, here is my update on private-machine. This is intended to give everyone an idea on how the CURRENT state of the project works. I pushed all my recent changes to
https://github.com/flamingrickpat/private-machine/tree/oop
In this branch, I try to adhere to proper enterprisy coding style. Now with *interfaces* and *inheritence* :o
I think I finally settled on an architecture.
>Architecture
Right now I have the system and the ghost. The system uses the str user input, generates a sensation impulse and passes it to the ghost. The ghost does all kind of stuff with that and in the end returns a output impulse.
The system (soon to be shell) is responsible for for handling IO and calling various cortexes. In the future there could be a visual cortex if you hook a multimodal model to a webcam or something. The shell would be responsible for queuing sensation impulses (user input from telegram, state change in webcam) and routing the output impulses (user output, change location in virtual world, switch camera).
>Shell
Just and idea, right now it turns str to Impulse.
>Ghost
This is the main event loop of the ghost:
```
def _tick_internal(self, impulse: Impulse) -> Impulse:
"""
Main event loop with possible recursion.
"""
self.depth += 1
self._start_subtick()
state = self._add_impulse(impulse)
self._eval_sensation(state)
self._choose_action(state)
while True:
temp_state = state.model_copy(deep=True)
self._plan_action(temp_state)
self._create_action(temp_state)
status = self._verify_action(temp_state)
if status:
state = temp_state
break
output = self._publish_output(state)
self._end_subtick()
return output
```
In my example here, I will use an user input request to change the living room lights from on to off.
>The impulse "can you turn off the living room" comes in
>_eval_sensation checks if the AI is in the right emotional state
>_choose_action instructs an agent to choose and action
```
def proces_state(self, state: GhostState):
allowed_actions = get_allowed_actions_for_impulse(state.sensation.impulse_type)
block = get_recent_messages_block(16, True)
action_selection = determine_action_type(block, allowed_actions)
content = None
action_type = ActionType[str(action_selection.action_type.value)]
if action_type == ActionType.InitiateUserConversation:
content = f"{companion_name} should message the user because of the following reasons: {action_selection.reason}"
elif action_type == ActionType.InitiateIdleMode:
content = f"{companion_name} should stay idle until the next heartbeat because of the following reasons: {action_selection.reason}"
elif action_type == ActionType.InitiateInternalContemplation:
content = f"{companion_name} should contemplate for the time being because of the following reasons: {action_selection.reason}"
elif action_type == ActionType.Reply:
content = f"{companion_name} should now reply to the user."
elif action_type == ActionType.Ignore:
content = f"{companion_name} should ignore this input because: {action_selection.reason}"
elif action_type == ActionType.ToolCall:
content = f"{companion_name} should use her AI companion abilities to make an API call: {action_selection.reason}"
```
>_plan_action does nothing
>_create_action creates an api call and executes it
```
def proces_state(self, state: GhostState):
ctx = get_recent_messages_block(6)
tool_type = determine_tools(ctx)
res = {}
tool = get_tool_call(ctx, tool_type)
tool.execute(res)
content = f"{companion_name} uses her AI powers to call the tool. The tool response: {res['output']}"
```
>_publish_output turns the tool_result output back into a sensation
>_eval_sensation checks if the AI is in the right emotional state (the tool call was successful, Emmy is proud and happy :D)
>_choose_action sees that the tool call is successful and chooses the reply action now
>_plan_action does nothing
>_create_action calls the story writing agent with the chatlog for the final output
>_publish_output returns an impulse with the user_output string
>Subsystems
There should be a shitload of possible subsystems in the future.
Emotions, needs, goals, personality, etc
And higher-order cognitive functions such as selective memory, introspection and meta-cognition.
I know I'm vague about this because I have only the most basic ideas of how it could work in my mind. Will update for more.
THe most basic ideas (for personality):
>use chatlog to extracted formalized facts
>categorize into semantic knowledge tree
>personality subsystem kicks in
>fetch nodes from "emmy/personality" node
Or for emotion
>save emotional state as basemodel with 6 floats 0 - 1 for emotions
>use the floats as bias for agent from agent group selection when executing emotion subsystem
>decay to baseline every tick
>every fact learned knows its tick and therefore its emotional state at that time
>feedback loop by retrieiving emotionally relevant memories (33% bias or somethng to regular vector search)
If you're unsure on how I could get the emotional state based on coversation, remember that LLMs can have structured output. I can literally force them to ouptut a JSON of a specific schema bis setting all unwanted logtis to -9999 or something. This way, I wan instruct my LLM to output a formalized emotion state analysis on any piece of dialog.
Will post more updates soon :)