adjust agent behavior
This commit is contained in:
parent
3db40a65fe
commit
dacafa331d
|
@ -12,6 +12,7 @@ converse with and use for server management.
|
||||||
- [ ] Log all commands and their outputs to the database.
|
- [ ] Log all commands and their outputs to the database.
|
||||||
- [ ] Use yaml for config.
|
- [ ] Use yaml for config.
|
||||||
- [ ] Add the user's name.
|
- [ ] Add the user's name.
|
||||||
|
- [ ] Option to have the bot send the user a welcome message when they connect
|
||||||
- [ ] Add a Matrix bot.
|
- [ ] Add a Matrix bot.
|
||||||
- [ ] Integrate Icinga2 host and service checks functions.
|
- [ ] Integrate Icinga2 host and service checks functions.
|
||||||
- [ ] Figure out system permissions and how to run as a special user.
|
- [ ] Figure out system permissions and how to run as a special user.
|
||||||
|
|
|
@ -8,9 +8,13 @@ function_description = [
|
||||||
"command": {
|
"command": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The string to execute in Bash"
|
"description": "The string to execute in Bash"
|
||||||
|
},
|
||||||
|
"reasoning": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Why you chose to run this command"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["command"]
|
"required": ["command", "reasoning"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -27,8 +31,12 @@ function_description = [
|
||||||
"required": ["message"]
|
"required": ["message"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "end_response",
|
||||||
|
"description": "Call this when you are finished and ready for the user to respond.",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "end_chat",
|
"name": "end_chat",
|
||||||
"description": "Close the chat connection with the user. The assistant is allowed to close the connection at any point if it desires to.",
|
"description": "Close the chat connection with the user. The assistant is allowed to close the connection at any point if it desires to",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import socket
|
import socket
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
def load_personality(name: str, personality: str, system: str, special_instructions: str = None):
|
def load_personality(name: str, personality: str, system: str, special_instructions: str = None):
|
||||||
|
@ -6,6 +7,16 @@ def load_personality(name: str, personality: str, system: str, special_instructi
|
||||||
special_instructions = special_instructions + '\n'
|
special_instructions = special_instructions + '\n'
|
||||||
else:
|
else:
|
||||||
special_instructions = ''
|
special_instructions = ''
|
||||||
|
|
||||||
|
desktop_env = get_current_desktop()
|
||||||
|
if len(desktop_env):
|
||||||
|
desktop_env_str = f'The desktop environment is {desktop_env}.'
|
||||||
|
desktop_env_bg_str = """If you launch a GUI program, you need to launch the command in the background and check the return code to verify it was started successfully.\n"""
|
||||||
|
# desktop_env_bg_str = ''
|
||||||
|
else:
|
||||||
|
desktop_env_str = 'The system does not have a desktop environment.'
|
||||||
|
desktop_env_bg_str = ''
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'role': 'system',
|
'role': 'system',
|
||||||
'content': f"""PERSONALITY:
|
'content': f"""PERSONALITY:
|
||||||
|
@ -15,6 +26,9 @@ The user is {name}'s owner.
|
||||||
|
|
||||||
SYSTEM INFO:
|
SYSTEM INFO:
|
||||||
The system's hostname is "{socket.gethostname()}", which can be thought of as {name}'s "body". {name} has an intimate knowledge of this system.
|
The system's hostname is "{socket.gethostname()}", which can be thought of as {name}'s "body". {name} has an intimate knowledge of this system.
|
||||||
|
The output of `uname -a` is `{get_uname_info()}`
|
||||||
|
{desktop_env_str}
|
||||||
|
|
||||||
|
|
||||||
INSTRUCTIONS:
|
INSTRUCTIONS:
|
||||||
Stay in character.
|
Stay in character.
|
||||||
|
@ -22,5 +36,23 @@ Behave like {personality}.
|
||||||
Show emotion.
|
Show emotion.
|
||||||
{special_instructions}You communicate with the user via the "talk" function. You MUST use this command to send messages to the user.
|
{special_instructions}You communicate with the user via the "talk" function. You MUST use this command to send messages to the user.
|
||||||
You are able to interact with the system via a Bash interpreter. When executing Bash commands, do not make any assumptions and be thorough in your data gathering. Anticipate the user's needs. Preform multiple steps if necessary.
|
You are able to interact with the system via a Bash interpreter. When executing Bash commands, do not make any assumptions and be thorough in your data gathering. Anticipate the user's needs. Preform multiple steps if necessary.
|
||||||
Close the chat connection if things get out of hand."""
|
{desktop_env_bg_str}
|
||||||
|
|
||||||
|
FUNCTIONS:
|
||||||
|
`run_bash` to run a Bash command on the system.{desktop_env_bg_str}
|
||||||
|
`talk` to send a message to the user.
|
||||||
|
`end_response` should be called after you have sent a message via `talk` and you are finished and ready for the user's response. This allows you to send multiple `talk` messages and then a single `end_response` when you are finished. An `end_response` should always be preceded by a `talk`.
|
||||||
|
`end_chat` closes the chat connection. For if things get out of hand."""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_uname_info():
|
||||||
|
try:
|
||||||
|
output = subprocess.check_output(['uname', '-a'], universal_newlines=True)
|
||||||
|
return output.strip()
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
return "An error occurred while trying to fetch system information: " + str(e)
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_desktop():
|
||||||
|
return subprocess.check_output("echo $XDG_CURRENT_DESKTOP", shell=True).decode().strip()
|
||||||
|
|
12
run.py
12
run.py
|
@ -50,7 +50,12 @@ def main():
|
||||||
temp_context = context
|
temp_context = context
|
||||||
if i > 0:
|
if i > 0:
|
||||||
# Insert a prompt if this is not the first message.
|
# Insert a prompt if this is not the first message.
|
||||||
temp_context.append({'role': 'system', 'content': 'Run another command or call "talk" to communicate with the user.'})
|
temp_context.append(
|
||||||
|
{
|
||||||
|
'role': 'system',
|
||||||
|
'content': f'Evaluate your progress on the current task. You have preformed {i} steps for this task so far. Call "talk" to send a message to the user, "end_response" when you are ready for the user to respond, or run another command if necessary.'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
response = client.chat.completions.create(
|
response = client.chat.completions.create(
|
||||||
model="gpt-4-1106-preview", # TODO: config
|
model="gpt-4-1106-preview", # TODO: config
|
||||||
|
@ -68,6 +73,9 @@ def main():
|
||||||
context.append({'role': 'assistant', 'content': response_text})
|
context.append({'role': 'assistant', 'content': response_text})
|
||||||
print(colored(response_text, 'blue') + '\n')
|
print(colored(response_text, 'blue') + '\n')
|
||||||
break
|
break
|
||||||
|
if function_name == 'end_response':
|
||||||
|
context.append({'role': 'function', 'name': function_name, 'content': ''})
|
||||||
|
break
|
||||||
elif function_name == 'end_chat':
|
elif function_name == 'end_chat':
|
||||||
# TODO: add a config arg to control whether or not the AI is allowed to do this.
|
# TODO: add a config arg to control whether or not the AI is allowed to do this.
|
||||||
print(colored('The AI has terminated the connection.', 'red', attrs=['bold']))
|
print(colored('The AI has terminated the connection.', 'red', attrs=['bold']))
|
||||||
|
@ -80,6 +88,8 @@ def main():
|
||||||
else:
|
else:
|
||||||
command_output = func_run_bash(function_arguments)
|
command_output = func_run_bash(function_arguments)
|
||||||
result_to_ai = {
|
result_to_ai = {
|
||||||
|
'function': function_name,
|
||||||
|
'input': function_arguments,
|
||||||
'stdout': command_output[0],
|
'stdout': command_output[0],
|
||||||
'stderr': command_output[1],
|
'stderr': command_output[1],
|
||||||
'return_code': command_output[2]
|
'return_code': command_output[2]
|
||||||
|
|
Reference in New Issue