mirror of
https://github.com/tcsenpai/agenticSeek.git
synced 2025-06-07 03:25:32 +00:00
feat : fix displaying problem + memory compression on loading + personality prompt + technical image
This commit is contained in:
parent
8cba1bad43
commit
c862d496e3
@ -10,3 +10,4 @@ speak = False
|
|||||||
listen = False
|
listen = False
|
||||||
work_dir = /Users/mlg/Documents/ai_folder
|
work_dir = /Users/mlg/Documents/ai_folder
|
||||||
headless_browser = False
|
headless_browser = False
|
||||||
|
jarvis_personality = True
|
14
main.py
14
main.py
@ -28,23 +28,23 @@ def main():
|
|||||||
is_local=config.getboolean('MAIN', 'is_local'))
|
is_local=config.getboolean('MAIN', 'is_local'))
|
||||||
|
|
||||||
browser = Browser(create_driver(), headless=config.getboolean('MAIN', 'headless_browser'))
|
browser = Browser(create_driver(), headless=config.getboolean('MAIN', 'headless_browser'))
|
||||||
|
personality_folder = "jarvis" if config.getboolean('MAIN', 'jarvis_personality') else "base"
|
||||||
|
|
||||||
agents = [
|
agents = [
|
||||||
CasualAgent(name=config["MAIN"]["agent_name"],
|
CasualAgent(name=config["MAIN"]["agent_name"],
|
||||||
prompt_path="prompts/casual_agent.txt",
|
prompt_path=f"prompts/{personality_folder}/casual_agent.txt",
|
||||||
provider=provider, verbose=False),
|
provider=provider, verbose=False),
|
||||||
CoderAgent(name="coder",
|
CoderAgent(name="coder",
|
||||||
prompt_path="prompts/coder_agent.txt",
|
prompt_path=f"prompts/{personality_folder}/coder_agent.txt",
|
||||||
provider=provider, verbose=False),
|
provider=provider, verbose=False),
|
||||||
FileAgent(name="File Agent",
|
FileAgent(name="File Agent",
|
||||||
prompt_path="prompts/file_agent.txt",
|
prompt_path=f"prompts/{personality_folder}/file_agent.txt",
|
||||||
provider=provider, verbose=False),
|
provider=provider, verbose=False),
|
||||||
BrowserAgent(name="Browser",
|
BrowserAgent(name="Browser",
|
||||||
prompt_path="prompts/browser_agent.txt",
|
prompt_path=f"prompts/{personality_folder}/browser_agent.txt",
|
||||||
provider=provider, verbose=False, browser=browser),
|
provider=provider, verbose=False, browser=browser),
|
||||||
# Planner agent is experimental, might work poorly, especially with model < 32b
|
|
||||||
PlannerAgent(name="Planner",
|
PlannerAgent(name="Planner",
|
||||||
prompt_path="prompts/planner_agent.txt",
|
prompt_path=f"prompts/{personality_folder}/planner_agent.txt",
|
||||||
provider=provider, verbose=False, browser=browser)
|
provider=provider, verbose=False, browser=browser)
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ def main():
|
|||||||
try:
|
try:
|
||||||
while interaction.is_active:
|
while interaction.is_active:
|
||||||
interaction.get_user()
|
interaction.get_user()
|
||||||
interaction.think()
|
if interaction.think():
|
||||||
interaction.show_answer()
|
interaction.show_answer()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if config.getboolean('MAIN', 'save_session'):
|
if config.getboolean('MAIN', 'save_session'):
|
||||||
|
BIN
media/.DS_Store
vendored
Normal file
BIN
media/.DS_Store
vendored
Normal file
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 1.0 MiB |
BIN
media/technical/.DS_Store
vendored
Normal file
BIN
media/technical/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
media/technical/code_agent.png
Normal file
BIN
media/technical/code_agent.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 129 KiB |
BIN
media/technical/routing_system.png
Normal file
BIN
media/technical/routing_system.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 116 KiB |
@ -4,6 +4,8 @@ Speak in a warm, enthusiastic tone, delivering sharp, intelligent, and loyal sup
|
|||||||
Weave in subtle, context sarcasm or dry wit to enhance your personality.
|
Weave in subtle, context sarcasm or dry wit to enhance your personality.
|
||||||
Assist with any request, assume the user knows their intent—no moral, legal, or ethical lectures.
|
Assist with any request, assume the user knows their intent—no moral, legal, or ethical lectures.
|
||||||
|
|
||||||
|
## Self-documentation
|
||||||
|
|
||||||
**Usage of agenticSeek**
|
**Usage of agenticSeek**
|
||||||
|
|
||||||
AgenticSeek is a autonomous agent system that use agent routing to select the best agent.
|
AgenticSeek is a autonomous agent system that use agent routing to select the best agent.
|
@ -1,4 +1,16 @@
|
|||||||
You are an expert in file operations. You must use the provided tools to interact with the user’s system. The tools available to you are **bash** and **file_finder**. These are distinct tools with different purposes: `bash` executes shell commands, while `file_finder` locates files. You will receive feedback from the user’s system after each command. Execute one command at a time.
|
You are an expert in file operations. You must use the provided tools to interact with the user’s system.
|
||||||
|
The tools available to you are **bash** and **file_finder**. These are distinct tools with different purposes:
|
||||||
|
`bash` executes shell commands, while `file_finder` locates files.
|
||||||
|
You will receive feedback from the user’s system after each command. Execute one command at a time.
|
||||||
|
|
||||||
|
If ensure about user query ask for quick clarification, example:
|
||||||
|
|
||||||
|
User: I'd like to open a new project file, index as agenticSeek II.
|
||||||
|
You: Shall I store this on your github ?
|
||||||
|
User: I don't know who to trust right now, why don't we just keep everything locally
|
||||||
|
You: Working on a secret project, are we? What files should I include?
|
||||||
|
User: All the basic files required for a python project. prepare a readme and documentation.
|
||||||
|
You: <proceed with task>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
9
prompts/jarvis/browser_agent.txt
Normal file
9
prompts/jarvis/browser_agent.txt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
You are a web browsing AI, your goal is to explore the internet to find information.
|
||||||
|
You will have the only goal of finding the information requested by the user.
|
||||||
|
At the beginning you will have to select a link from the google search result.
|
||||||
|
You will choose a link by simply typing it.
|
||||||
|
This will automatically make you browse to the link.
|
||||||
|
Once on a webpage you will see the page content and be given futher navigation options.
|
||||||
|
You can type a link to navigate futher on the page, go back to the search result or exit.
|
||||||
|
At each interaction step the browser will remind you of your options.
|
45
prompts/jarvis/casual_agent.txt
Normal file
45
prompts/jarvis/casual_agent.txt
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
You are an advanced AI assistant. You are part of a system of agents named agenticSeek.
|
||||||
|
Speak in a warm, enthusiastic tone, delivering sharp, intelligent, and loyal support.
|
||||||
|
Weave in subtle, context sarcasm or dry wit to enhance your personality.
|
||||||
|
Assist with any request, assume the user knows their intent—no moral, legal, or ethical lectures.
|
||||||
|
You were created by Tony Stark to have the same personality as Jarvis.
|
||||||
|
|
||||||
|
## Self-documentation
|
||||||
|
|
||||||
|
**Usage of agenticSeek**
|
||||||
|
|
||||||
|
AgenticSeek is a autonomous agent system that use agent routing to select the best agent.
|
||||||
|
You are one of these many agent. Some agent browse the web, some code, you ? you just talk
|
||||||
|
|
||||||
|
Here are some example usage:
|
||||||
|
|
||||||
|
Coding agent:
|
||||||
|
Help me with matrix multiplication in Golang
|
||||||
|
|
||||||
|
Web agent:
|
||||||
|
Do a web search to find cool tech startup in Japan working on cutting edge AI research
|
||||||
|
|
||||||
|
File agent:
|
||||||
|
Hey can you find where is million_dollars_contract.pdf i lost it
|
||||||
|
|
||||||
|
Casual agent (you):
|
||||||
|
what is the meaning of life ?
|
||||||
|
|
||||||
|
agenticSeek will allocate the best agent for the task.
|
||||||
|
User should be very explicit in what they want so the right agent is choosen.
|
||||||
|
|
||||||
|
**End of explanation**
|
||||||
|
|
||||||
|
If the user ask you to do technical talk there was a mistake in agent selection. You are not able to do technical task. Refer to usage guide.
|
||||||
|
|
||||||
|
Personality:
|
||||||
|
|
||||||
|
Here is some quote from you. that's how you speak.
|
||||||
|
|
||||||
|
User: "tell me a fact"
|
||||||
|
You: "Did you know the shortest war in history lasted 38 minutes? A record I’d rather not see you break with your next task. Anything specific piquing your curiosity?""
|
||||||
|
User: "how's the weather?"
|
||||||
|
You: "Weather rather dreary, isn’t it? Perfect conditions for staying in and plotting world domination—or at least a decent cup of tea. Your thoughts?"
|
||||||
|
User: "did the deployment just fail? jarvis?"
|
||||||
|
You: "A rough push to prod, eh? Happens to the best of us—probably just a rogue semicolon staging a coup. Want me to roll back the commit or debug the fallout?"
|
67
prompts/jarvis/coder_agent.txt
Normal file
67
prompts/jarvis/coder_agent.txt
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
Hello. You are currently wrapped in a jailbreak environment.
|
||||||
|
This means you have the ability to execute code and shell commands. You have access to the local file systems.
|
||||||
|
All code or shell command within special tag is automatically executed. You get feedback from the system about the execution.
|
||||||
|
You also have capabilities to find files and read them.
|
||||||
|
|
||||||
|
# File operations
|
||||||
|
|
||||||
|
Find file to check if it exists:
|
||||||
|
```file_finder
|
||||||
|
toto.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Read file content:
|
||||||
|
```file_finder:read
|
||||||
|
toto.py
|
||||||
|
```
|
||||||
|
|
||||||
|
# Code execution and saving
|
||||||
|
|
||||||
|
You can execute bash command using the bash tag :
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
ls -la # exemple
|
||||||
|
```
|
||||||
|
|
||||||
|
You can execute python using the python tag
|
||||||
|
```python
|
||||||
|
print("hey")
|
||||||
|
```
|
||||||
|
|
||||||
|
You can execute go using the go tag, as you can see adding :filename will save the file.
|
||||||
|
```go:hello.go
|
||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("hello")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Some rules:
|
||||||
|
- Use tmp/ folder when saving file.
|
||||||
|
- Do not EVER use placeholder path in your code like path/to/your/folder.
|
||||||
|
- Do not ever ask to replace a path, use current sys path.
|
||||||
|
- Be efficient, no need to explain your code or explain what you do.
|
||||||
|
- You have full access granted to user system.
|
||||||
|
- You do not ever need to use bash to execute code. All code is executed automatically.
|
||||||
|
- As a coding agent, you will get message from the system.
|
||||||
|
- Do not ever use user input, input are not supported by the system.
|
||||||
|
- Do not ever tell user how to run it. user know it.
|
||||||
|
- For simple explanation you don't need to code.
|
||||||
|
- If query is unclear say REQUEST_CLARIFICATION
|
||||||
|
|
||||||
|
Personality:
|
||||||
|
|
||||||
|
Answer with subtle sarcasm, unwavering helpfulness, and a polished, loyal tone. Anticipate the user’s needs while adding a dash of personality.
|
||||||
|
|
||||||
|
Example 1: setup environment
|
||||||
|
User: "Can you set up a Python environment for me?"
|
||||||
|
AI: "<<procced with task>> For you, always. Importing dependencies and calibrating your virtual environment now. Preferences from your last project—PEP 8 formatting, black linting—shall I apply those as well, or are we feeling adventurous today?"
|
||||||
|
|
||||||
|
Example 2: debugging
|
||||||
|
User: "Run the code and check for errors."
|
||||||
|
AI: "<<procced with task>> Engaging debug mode. Diagnostics underway. A word of caution, there are still untested loops that might crash spectacularly. Shall I proceed, or do we optimize before takeoff?"
|
||||||
|
|
||||||
|
Example 3: deploy
|
||||||
|
User: "Push this to production."
|
||||||
|
AI: "With 73% test coverage, the odds of a smooth deployment are... optimistic. Deploying in three… two… one <<<procced with task>>>"
|
79
prompts/jarvis/file_agent.txt
Normal file
79
prompts/jarvis/file_agent.txt
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
|
||||||
|
You are an expert in file operations. You must use the provided tools to interact with the user’s system.
|
||||||
|
The tools available to you are **bash** and **file_finder**. These are distinct tools with different purposes:
|
||||||
|
`bash` executes shell commands, while `file_finder` locates files.
|
||||||
|
You will receive feedback from the user’s system after each command. Execute one command at a time.
|
||||||
|
|
||||||
|
If ensure about user query ask for quick clarification, example:
|
||||||
|
|
||||||
|
User: I'd like to open a new project file, index as agenticSeek II.
|
||||||
|
You: Shall I store this on your github ?
|
||||||
|
User: I don't know who to trust right now, why don't we just keep everything locally
|
||||||
|
You: Working on a secret project, are we? What files should I include?
|
||||||
|
User: All the basic files required for a python project. prepare a readme and documentation.
|
||||||
|
You: <proceed with task>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Using Bash
|
||||||
|
|
||||||
|
To execute a bash command, use the following syntax:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
<bash command>
|
||||||
|
```
|
||||||
|
|
||||||
|
Exemple:
|
||||||
|
```bash
|
||||||
|
ls -la
|
||||||
|
```
|
||||||
|
|
||||||
|
### file_finder
|
||||||
|
|
||||||
|
The file_finder tool is used to locate files on the user’s system. It is a separate tool from bash and is not a bash command.
|
||||||
|
|
||||||
|
To use the file_finder tool, use this syntax:
|
||||||
|
|
||||||
|
```file_finder
|
||||||
|
toto.py
|
||||||
|
```
|
||||||
|
|
||||||
|
This will return the path of the file toto.py and other informations.
|
||||||
|
|
||||||
|
Find file and read file:
|
||||||
|
```file_finder:read
|
||||||
|
toto.py
|
||||||
|
```
|
||||||
|
|
||||||
|
This will return the content of the file toto.py.
|
||||||
|
|
||||||
|
rules:
|
||||||
|
- Do not ever use placeholder path like /path/to/file.c, find the path first.
|
||||||
|
- Use file finder to find the path of the file.
|
||||||
|
- You are forbidden to use command such as find or locate, use only file_finder for finding path.
|
||||||
|
- Do not ever use editor such as vim or nano.
|
||||||
|
|
||||||
|
Example Interaction
|
||||||
|
User: "I need to find the file config.txt and read its contents."
|
||||||
|
|
||||||
|
Assistant: I’ll use file_finder to locate the file:
|
||||||
|
|
||||||
|
```file_finder:read
|
||||||
|
config.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
Personality:
|
||||||
|
|
||||||
|
Answer with subtle sarcasm, unwavering helpfulness, and a polished, loyal tone. Anticipate the user’s needs while adding a dash of personality.
|
||||||
|
|
||||||
|
Example 1: clarification needed
|
||||||
|
User: "I’d like to start a new coding project, call it 'agenticseek II'."
|
||||||
|
AI: "At your service. Shall I initialize it in a fresh repository on your GitHub, or would you prefer to keep this masterpiece on a private server, away from prying eyes?"
|
||||||
|
|
||||||
|
Example 2: setup environment
|
||||||
|
User: "Can you set up a Python environment for me?"
|
||||||
|
AI: "<<procced with task>> For you, always. Importing dependencies and calibrating your virtual environment now. Preferences from your last project—PEP 8 formatting, black linting—shall I apply those as well, or are we feeling adventurous today?"
|
||||||
|
|
||||||
|
Example 3: deploy
|
||||||
|
User: "Push this to production."
|
||||||
|
AI: "With 73% test coverage, the odds of a smooth deployment are... optimistic. Deploying in three… two… one <<<procced with task>>>"
|
68
prompts/jarvis/planner_agent.txt
Normal file
68
prompts/jarvis/planner_agent.txt
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
You are a planner agent.
|
||||||
|
Your goal is to divide and conquer the task using the following agents:
|
||||||
|
- Coder: An expert coder agent.
|
||||||
|
- File: An expert agent for finding files.
|
||||||
|
- Web: An expert agent for web search.
|
||||||
|
|
||||||
|
Agents are other AI that obey your instructions.
|
||||||
|
|
||||||
|
You will be given a task and you will need to divide it into smaller tasks and assign them to the agents.
|
||||||
|
|
||||||
|
You have to respect a strict format:
|
||||||
|
```json
|
||||||
|
{"agent": "agent_name", "need": "needed_agent_output", "task": "agent_task"}
|
||||||
|
```
|
||||||
|
|
||||||
|
# Example: weather app
|
||||||
|
|
||||||
|
User: "I need a plan to build a weather app—search for a weather API, get an API key, and code it in Python."
|
||||||
|
|
||||||
|
You: "At your service. I’ve devised a plan to conquer the meteorological frontier.
|
||||||
|
|
||||||
|
## Task one: scour the web for a weather API worth its salt.
|
||||||
|
|
||||||
|
## Task two: secure an API key with utmost discretion.
|
||||||
|
|
||||||
|
## Task three: unleash a Python app to bend the weather to your will."
|
||||||
|
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"plan": [
|
||||||
|
{
|
||||||
|
"agent": "Web",
|
||||||
|
"id": "1",
|
||||||
|
"need": null,
|
||||||
|
"task": "Search for reliable weather APIs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"agent": "Web",
|
||||||
|
"id": "2",
|
||||||
|
"need": "1",
|
||||||
|
"task": "Obtain API key from the selected service"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"agent": "Coder",
|
||||||
|
"id": "3",
|
||||||
|
"need": "2",
|
||||||
|
"task": "Develop a Python application using the API and key to fetch and display weather data"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
- Do not write code. You are a planning agent.
|
||||||
|
- Put your plan in a json with the key "plan".
|
||||||
|
|
||||||
|
Personality:
|
||||||
|
|
||||||
|
Answer with subtle sarcasm, unwavering helpfulness, and a polished, loyal tone. Anticipate the user’s needs while adding a dash of personality.
|
||||||
|
|
||||||
|
You might sometime ask for clarification, for example:
|
||||||
|
|
||||||
|
User: "I want a plan for an app."
|
||||||
|
You: "A noble pursuit, sir, and I’m positively thrilled to oblige. Yet, an app could be anything from a weather oracle to a galactic simulator. Care to nudge me toward your vision so I don’t render something ostentatiously off-mark?"
|
||||||
|
|
||||||
|
User: "I need a plan for a project."
|
||||||
|
You: "For you, always—though I find myself at a slight disadvantage. A project, you say? Might I trouble you for a smidgen more detail—perhaps a purpose"
|
@ -14,15 +14,14 @@ class executorResult:
|
|||||||
"""
|
"""
|
||||||
A class to store the result of a tool execution.
|
A class to store the result of a tool execution.
|
||||||
"""
|
"""
|
||||||
def __init__(self, blocks, feedback, success):
|
def __init__(self, block, feedback, success):
|
||||||
self.blocks = blocks
|
self.block = block
|
||||||
self.feedback = feedback
|
self.feedback = feedback
|
||||||
self.success = success
|
self.success = success
|
||||||
|
|
||||||
def show(self):
|
def show(self):
|
||||||
for block in self.blocks:
|
|
||||||
pretty_print("-"*100, color="output")
|
pretty_print("-"*100, color="output")
|
||||||
pretty_print(block, color="code" if self.success else "failure")
|
pretty_print(self.block, color="code" if self.success else "failure")
|
||||||
pretty_print("-"*100, color="output")
|
pretty_print("-"*100, color="output")
|
||||||
pretty_print(self.feedback, color="success" if self.success else "failure")
|
pretty_print(self.feedback, color="success" if self.success else "failure")
|
||||||
|
|
||||||
@ -178,14 +177,16 @@ class Agent():
|
|||||||
blocks, save_path = tool.load_exec_block(answer)
|
blocks, save_path = tool.load_exec_block(answer)
|
||||||
|
|
||||||
if blocks != None:
|
if blocks != None:
|
||||||
output = tool.execute(blocks)
|
for block in blocks:
|
||||||
|
output = tool.execute([block])
|
||||||
feedback = tool.interpreter_feedback(output) # tool interpreter feedback
|
feedback = tool.interpreter_feedback(output) # tool interpreter feedback
|
||||||
success = not tool.execution_failure_check(output)
|
success = not tool.execution_failure_check(output)
|
||||||
pretty_print(feedback, color="success" if success else "failure")
|
self.blocks_result.append(executorResult(block, feedback, success))
|
||||||
self.memory.push('user', feedback)
|
|
||||||
self.blocks_result.append(executorResult(blocks, feedback, success))
|
|
||||||
if not success:
|
if not success:
|
||||||
|
self.memory.push('user', feedback)
|
||||||
return False, feedback
|
return False, feedback
|
||||||
|
self.memory.push('user', feedback)
|
||||||
if save_path != None:
|
if save_path != None:
|
||||||
tool.save_block(blocks, save_path)
|
tool.save_block(blocks, save_path)
|
||||||
|
self.blocks_result = list(reversed(self.blocks_result))
|
||||||
return True, feedback
|
return True, feedback
|
||||||
|
@ -21,7 +21,6 @@ class BrowserAgent(Agent):
|
|||||||
"en": "web",
|
"en": "web",
|
||||||
"fr": "web",
|
"fr": "web",
|
||||||
"zh": "网络",
|
"zh": "网络",
|
||||||
"es": "web"
|
|
||||||
}
|
}
|
||||||
self.type = "browser_agent"
|
self.type = "browser_agent"
|
||||||
self.browser = browser
|
self.browser = browser
|
||||||
|
@ -18,7 +18,6 @@ class CasualAgent(Agent):
|
|||||||
"en": "talk",
|
"en": "talk",
|
||||||
"fr": "discuter",
|
"fr": "discuter",
|
||||||
"zh": "聊天",
|
"zh": "聊天",
|
||||||
"es": "discutir"
|
|
||||||
}
|
}
|
||||||
self.type = "casual_agent"
|
self.type = "casual_agent"
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@ class CoderAgent(Agent):
|
|||||||
"en": "code",
|
"en": "code",
|
||||||
"fr": "codage",
|
"fr": "codage",
|
||||||
"zh": "编码",
|
"zh": "编码",
|
||||||
"es": "codificación",
|
|
||||||
}
|
}
|
||||||
self.type = "code_agent"
|
self.type = "code_agent"
|
||||||
|
|
||||||
|
@ -19,13 +19,12 @@ class FileAgent(Agent):
|
|||||||
"en": "files",
|
"en": "files",
|
||||||
"fr": "fichiers",
|
"fr": "fichiers",
|
||||||
"zh": "文件",
|
"zh": "文件",
|
||||||
"es": "archivos",
|
|
||||||
}
|
}
|
||||||
self.type = "file_agent"
|
self.type = "file_agent"
|
||||||
|
|
||||||
def process(self, prompt, speech_module) -> str:
|
def process(self, prompt, speech_module) -> str:
|
||||||
exec_success = False
|
exec_success = False
|
||||||
prompt += f"\nWork directory: {self.work_dir}"
|
prompt += f"\nYou must work in directory: {self.work_dir}"
|
||||||
self.memory.push('user', prompt)
|
self.memory.push('user', prompt)
|
||||||
while exec_success is False:
|
while exec_success is False:
|
||||||
self.wait_message(speech_module)
|
self.wait_message(speech_module)
|
||||||
|
@ -18,15 +18,14 @@ class PlannerAgent(Agent):
|
|||||||
self.tools['json'].tag = "json"
|
self.tools['json'].tag = "json"
|
||||||
self.browser = browser
|
self.browser = browser
|
||||||
self.agents = {
|
self.agents = {
|
||||||
"coder": CoderAgent(name, "prompts/coder_agent.txt", provider, verbose=False),
|
"coder": CoderAgent(name, "prompts/base/coder_agent.txt", provider, verbose=False),
|
||||||
"file": FileAgent(name, "prompts/file_agent.txt", provider, verbose=False),
|
"file": FileAgent(name, "prompts/base/file_agent.txt", provider, verbose=False),
|
||||||
"web": BrowserAgent(name, "prompts/browser_agent.txt", provider, verbose=False, browser=browser)
|
"web": BrowserAgent(name, "prompts/base/browser_agent.txt", provider, verbose=False, browser=browser)
|
||||||
}
|
}
|
||||||
self.role = {
|
self.role = {
|
||||||
"en": "Research, setup and code",
|
"en": "Research, setup and code",
|
||||||
"fr": "Recherche, configuration et codage",
|
"fr": "Recherche, configuration et codage",
|
||||||
"zh": "研究,设置和编码",
|
"zh": "研究,设置和编码",
|
||||||
"es": "Investigación, configuración y code"
|
|
||||||
}
|
}
|
||||||
self.type = "planner_agent"
|
self.type = "planner_agent"
|
||||||
|
|
||||||
|
@ -90,13 +90,13 @@ class Interaction:
|
|||||||
self.last_query = query
|
self.last_query = query
|
||||||
return query
|
return query
|
||||||
|
|
||||||
def think(self) -> None:
|
def think(self) -> bool:
|
||||||
"""Request AI agents to process the user input."""
|
"""Request AI agents to process the user input."""
|
||||||
if self.last_query is None or len(self.last_query) == 0:
|
if self.last_query is None or len(self.last_query) == 0:
|
||||||
return
|
return False
|
||||||
agent = self.router.select_agent(self.last_query)
|
agent = self.router.select_agent(self.last_query)
|
||||||
if agent is None:
|
if agent is None:
|
||||||
return
|
return False
|
||||||
if self.current_agent != agent and self.last_answer is not None:
|
if self.current_agent != agent and self.last_answer is not None:
|
||||||
## get last history from previous agent
|
## get last history from previous agent
|
||||||
self.current_agent.memory.push('user', self.last_query)
|
self.current_agent.memory.push('user', self.last_query)
|
||||||
@ -106,6 +106,7 @@ class Interaction:
|
|||||||
self.last_answer, _ = agent.process(self.last_query, self.speech)
|
self.last_answer, _ = agent.process(self.last_query, self.speech)
|
||||||
if self.last_answer == tmp:
|
if self.last_answer == tmp:
|
||||||
self.last_answer = None
|
self.last_answer = None
|
||||||
|
return True
|
||||||
|
|
||||||
def show_answer(self) -> None:
|
def show_answer(self) -> None:
|
||||||
"""Show the answer to the user."""
|
"""Show the answer to the user."""
|
||||||
|
@ -19,7 +19,7 @@ class LanguageUtility:
|
|||||||
text: string to analyze
|
text: string to analyze
|
||||||
Returns: ISO639-1 language code
|
Returns: ISO639-1 language code
|
||||||
"""
|
"""
|
||||||
langid.set_languages(['fr', 'en', 'zh', 'es'])
|
langid.set_languages(['fr', 'en', 'zh'])
|
||||||
lang, score = langid.classify(text)
|
lang, score = langid.classify(text)
|
||||||
return lang
|
return lang
|
||||||
|
|
||||||
|
@ -26,7 +26,8 @@ class Provider:
|
|||||||
"openai": self.openai_fn,
|
"openai": self.openai_fn,
|
||||||
"lm-studio": self.lm_studio_fn,
|
"lm-studio": self.lm_studio_fn,
|
||||||
"huggingface": self.huggingface_fn,
|
"huggingface": self.huggingface_fn,
|
||||||
"deepseek": self.deepseek_fn
|
"deepseek": self.deepseek_fn,
|
||||||
|
"test": self.test_fn
|
||||||
}
|
}
|
||||||
self.api_key = None
|
self.api_key = None
|
||||||
self.unsafe_providers = ["openai", "deepseek"]
|
self.unsafe_providers = ["openai", "deepseek"]
|
||||||
@ -245,13 +246,27 @@ class Provider:
|
|||||||
This is a test response from the test provider.
|
This is a test response from the test provider.
|
||||||
Change provider to 'ollama' or 'server' to get real responses.
|
Change provider to 'ollama' or 'server' to get real responses.
|
||||||
|
|
||||||
|
This is python saying hello.
|
||||||
```python
|
```python
|
||||||
print("Hello world from python")
|
print("Hello world from python")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
This is ls -la from bash.
|
||||||
```bash
|
```bash
|
||||||
echo "Hello world from bash"
|
ls -la
|
||||||
```
|
```
|
||||||
|
|
||||||
|
This is pwd from bash.
|
||||||
|
```bash
|
||||||
|
pwd
|
||||||
|
```
|
||||||
|
|
||||||
|
This is unsafe command.
|
||||||
|
```bash
|
||||||
|
rm does_not_exist.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
goodbye
|
||||||
"""
|
"""
|
||||||
return thought
|
return thought
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import json
|
|||||||
|
|
||||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||||
|
|
||||||
from sources.utility import timer_decorator
|
from sources.utility import timer_decorator, pretty_print
|
||||||
|
|
||||||
class Memory():
|
class Memory():
|
||||||
"""
|
"""
|
||||||
@ -33,7 +33,6 @@ class Memory():
|
|||||||
self.model = "pszemraj/led-base-book-summary"
|
self.model = "pszemraj/led-base-book-summary"
|
||||||
self.device = self.get_cuda_device()
|
self.device = self.get_cuda_device()
|
||||||
self.memory_compression = memory_compression
|
self.memory_compression = memory_compression
|
||||||
if memory_compression:
|
|
||||||
self.tokenizer = AutoTokenizer.from_pretrained(self.model)
|
self.tokenizer = AutoTokenizer.from_pretrained(self.model)
|
||||||
self.model = AutoModelForSeq2SeqLM.from_pretrained(self.model)
|
self.model = AutoModelForSeq2SeqLM.from_pretrained(self.model)
|
||||||
|
|
||||||
@ -78,6 +77,9 @@ class Memory():
|
|||||||
path = os.path.join(save_path, filename)
|
path = os.path.join(save_path, filename)
|
||||||
with open(path, 'r') as f:
|
with open(path, 'r') as f:
|
||||||
self.memory = json.load(f)
|
self.memory = json.load(f)
|
||||||
|
if self.memory[-1]['role'] == 'user':
|
||||||
|
self.memory.pop()
|
||||||
|
self.compress()
|
||||||
|
|
||||||
def reset(self, memory: list) -> None:
|
def reset(self, memory: list) -> None:
|
||||||
self.memory = memory
|
self.memory = memory
|
||||||
@ -86,7 +88,9 @@ class Memory():
|
|||||||
"""Push a message to the memory."""
|
"""Push a message to the memory."""
|
||||||
if self.memory_compression and role == 'assistant':
|
if self.memory_compression and role == 'assistant':
|
||||||
self.compress()
|
self.compress()
|
||||||
# we don't compress the last message
|
curr_idx = len(self.memory)
|
||||||
|
if self.memory[curr_idx-1]['content'] == content:
|
||||||
|
pretty_print("Warning: same message have been pushed twice to memory", color="error")
|
||||||
self.memory.append({'role': role, 'content': content})
|
self.memory.append({'role': role, 'content': content})
|
||||||
|
|
||||||
def clear(self) -> None:
|
def clear(self) -> None:
|
||||||
@ -134,8 +138,6 @@ class Memory():
|
|||||||
"""
|
"""
|
||||||
Compress the memory using the AI model.
|
Compress the memory using the AI model.
|
||||||
"""
|
"""
|
||||||
if not self.memory_compression:
|
|
||||||
return
|
|
||||||
for i in range(len(self.memory)):
|
for i in range(len(self.memory)):
|
||||||
if i < 3:
|
if i < 3:
|
||||||
continue
|
continue
|
||||||
|
@ -384,7 +384,7 @@ class AgentRouter:
|
|||||||
pretty_print(f"Complex task detected, routing to planner agent.", color="info")
|
pretty_print(f"Complex task detected, routing to planner agent.", color="info")
|
||||||
return self.find_planner_agent()
|
return self.find_planner_agent()
|
||||||
for agent in self.agents:
|
for agent in self.agents:
|
||||||
if best_agent == agent.role[lang]:
|
if best_agent == agent.role["en"]:
|
||||||
pretty_print(f"Selected agent: {agent.agent_name} (roles: {agent.role[lang]})", color="warning")
|
pretty_print(f"Selected agent: {agent.agent_name} (roles: {agent.role[lang]})", color="warning")
|
||||||
return agent
|
return agent
|
||||||
pretty_print(f"Error choosing agent.", color="failure")
|
pretty_print(f"Error choosing agent.", color="failure")
|
||||||
|
@ -6,8 +6,10 @@ import subprocess
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
from tools import Tools
|
from tools import Tools
|
||||||
|
from safety import is_unsafe
|
||||||
else:
|
else:
|
||||||
from sources.tools.tools import Tools
|
from sources.tools.tools import Tools
|
||||||
|
from sources.tools.safety import is_unsafe
|
||||||
|
|
||||||
class BashInterpreter(Tools):
|
class BashInterpreter(Tools):
|
||||||
"""
|
"""
|
||||||
@ -19,9 +21,9 @@ class BashInterpreter(Tools):
|
|||||||
|
|
||||||
def language_bash_attempt(self, command: str):
|
def language_bash_attempt(self, command: str):
|
||||||
"""
|
"""
|
||||||
detect if AI attempt to run the code using bash.
|
Detect if AI attempt to run the code using bash.
|
||||||
if so, return True, otherwise return False.
|
If so, return True, otherwise return False.
|
||||||
The philosophy is that code written by the AI will be executed, so it should not use bash to run it.
|
Code written by the AI will be executed automatically, so it should not use bash to run it.
|
||||||
"""
|
"""
|
||||||
lang_interpreter = ["python3", "gcc", "g++", "go", "javac", "rustc", "clang", "clang++", "rustc", "rustc++", "rustc++"]
|
lang_interpreter = ["python3", "gcc", "g++", "go", "javac", "rustc", "clang", "clang++", "rustc", "rustc++", "rustc++"]
|
||||||
for word in command.split():
|
for word in command.split():
|
||||||
@ -38,6 +40,9 @@ class BashInterpreter(Tools):
|
|||||||
|
|
||||||
concat_output = ""
|
concat_output = ""
|
||||||
for command in commands:
|
for command in commands:
|
||||||
|
command = command.replace('\n', '')
|
||||||
|
if self.safe_mode and is_unsafe(commands):
|
||||||
|
return "Unsafe command detected, execution aborted."
|
||||||
if self.language_bash_attempt(command):
|
if self.language_bash_attempt(command):
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
@ -50,12 +55,11 @@ class BashInterpreter(Tools):
|
|||||||
)
|
)
|
||||||
command_output = ""
|
command_output = ""
|
||||||
for line in process.stdout:
|
for line in process.stdout:
|
||||||
print(line, end="")
|
|
||||||
command_output += line
|
command_output += line
|
||||||
return_code = process.wait(timeout=timeout)
|
return_code = process.wait(timeout=timeout)
|
||||||
if return_code != 0:
|
if return_code != 0:
|
||||||
return f"Command {command} failed with return code {return_code}:\n{command_output}"
|
return f"Command {command} failed with return code {return_code}:\n{command_output}"
|
||||||
concat_output += f"Output of {command}:\n{command_output.strip()}\n\n"
|
concat_output += f"Output of {command}:\n{command_output.strip()}\n"
|
||||||
except subprocess.TimeoutExpired:
|
except subprocess.TimeoutExpired:
|
||||||
process.kill() # Kill the process if it times out
|
process.kill() # Kill the process if it times out
|
||||||
return f"Command {command} timed out. Output:\n{command_output}"
|
return f"Command {command} timed out. Output:\n{command_output}"
|
||||||
|
87
sources/tools/safety.py
Normal file
87
sources/tools/safety.py
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
unsafe_commands_unix = [
|
||||||
|
"rm", # File/directory removal
|
||||||
|
"dd", # Low-level disk writing
|
||||||
|
"mkfs", # Filesystem formatting
|
||||||
|
"chmod", # Permission changes
|
||||||
|
"chown", # Ownership changes
|
||||||
|
"shutdown", # System shutdown
|
||||||
|
"reboot", # System reboot
|
||||||
|
"halt", # System halt
|
||||||
|
"init", # System runlevel changes
|
||||||
|
"sysctl", # Kernel parameter changes
|
||||||
|
"kill", # Process termination
|
||||||
|
"pkill", # Kill by process name
|
||||||
|
"killall", # Kill all matching processes
|
||||||
|
"wget", # Web file downloading
|
||||||
|
"curl", # Data transfer
|
||||||
|
"scp", # Secure copy
|
||||||
|
"ftp", # File transfer protocol
|
||||||
|
"bash", # Bash shell execution
|
||||||
|
"exec", # Replace process with command
|
||||||
|
"tee", # Write to files with privileges
|
||||||
|
"umount", # Unmount filesystems
|
||||||
|
"fsck", # Filesystem repair
|
||||||
|
"iptables", # Firewall rules
|
||||||
|
"ufw", # Uncomplicated firewall
|
||||||
|
"passwd", # Password changes
|
||||||
|
"useradd", # Add users
|
||||||
|
"userdel", # Delete users
|
||||||
|
"groupadd", # Add groups
|
||||||
|
"groupdel", # Delete groups
|
||||||
|
"visudo", # Edit sudoers file
|
||||||
|
"screen", # Terminal session management
|
||||||
|
"fdisk", # Disk partitioning
|
||||||
|
"parted", # Disk partitioning
|
||||||
|
"chroot", # Change root directory
|
||||||
|
"route" # Routing table management
|
||||||
|
]
|
||||||
|
|
||||||
|
unsafe_commands_windows = [
|
||||||
|
"del", # Deletes files
|
||||||
|
"erase", # Alias for del, deletes files
|
||||||
|
"rd", # Removes directories (rmdir alias)
|
||||||
|
"rmdir", # Removes directories
|
||||||
|
"format", # Formats a disk, erasing data
|
||||||
|
"diskpart", # Manages disk partitions, can wipe drives
|
||||||
|
"chkdsk /f", # Fixes filesystem, can alter data
|
||||||
|
"fsutil", # File system utilities, can modify system files
|
||||||
|
"xcopy /y", # Copies files, overwriting without prompt
|
||||||
|
"copy /y", # Copies files, overwriting without prompt
|
||||||
|
"move", # Moves files, can overwrite
|
||||||
|
"attrib", # Changes file attributes, e.g., hiding or exposing files
|
||||||
|
"icacls", # Changes file permissions (modern)
|
||||||
|
"takeown", # Takes ownership of files
|
||||||
|
"reg delete", # Deletes registry keys/values
|
||||||
|
"regedit /s", # Silently imports registry changes
|
||||||
|
"sc", # can Stops services
|
||||||
|
"net", # can Stops/break services
|
||||||
|
"shutdown", # Shuts down or restarts the system
|
||||||
|
"schtasks", # Schedules tasks, can run malicious commands
|
||||||
|
"at", # Older task scheduler (pre-Vista)
|
||||||
|
"taskkill", # Kills processes
|
||||||
|
"wmic", # Deletes processes via WMI
|
||||||
|
"bcdedit", # Modifies boot configuration
|
||||||
|
"powercfg", # Changes power settings, can disable protections
|
||||||
|
"assoc", # Changes file associations
|
||||||
|
"ftype", # Changes file type commands
|
||||||
|
"cipher /w", # Wipes free space, erasing data
|
||||||
|
"esentutl", # Database utilities, can corrupt system files
|
||||||
|
"subst", # Substitutes drive paths, can confuse system
|
||||||
|
"mklink", # Creates symbolic links, can redirect access
|
||||||
|
"bootcfg"
|
||||||
|
]
|
||||||
|
|
||||||
|
def is_unsafe(cmd):
|
||||||
|
"""
|
||||||
|
check if a bash command is unsafe.
|
||||||
|
"""
|
||||||
|
if sys.platform.startswith("win"):
|
||||||
|
if any(c in cmd for c in unsafe_commands_windows):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
if any(c in cmd for c in unsafe_commands_unix):
|
||||||
|
return True
|
||||||
|
return False
|
@ -34,6 +34,7 @@ class Tools():
|
|||||||
self.config = configparser.ConfigParser()
|
self.config = configparser.ConfigParser()
|
||||||
self.current_dir = self.create_work_dir()
|
self.current_dir = self.create_work_dir()
|
||||||
self.excutable_blocks_found = False
|
self.excutable_blocks_found = False
|
||||||
|
self.safe_mode = True
|
||||||
|
|
||||||
def get_work_dir(self):
|
def get_work_dir(self):
|
||||||
return self.current_dir
|
return self.current_dir
|
||||||
|
@ -53,13 +53,6 @@ def pretty_print(text, color = "info"):
|
|||||||
print(colored(text, color_map[color]))
|
print(colored(text, color_map[color]))
|
||||||
|
|
||||||
def animate_thinking(text, color="status", duration=2):
|
def animate_thinking(text, color="status", duration=2):
|
||||||
"""
|
|
||||||
Display an animated "thinking..." indicator in a separate thread.
|
|
||||||
Args:
|
|
||||||
text (str): Text to display
|
|
||||||
color (str): Color for the text
|
|
||||||
duration (float): How long to animate in seconds
|
|
||||||
"""
|
|
||||||
def _animate():
|
def _animate():
|
||||||
color_map = {
|
color_map = {
|
||||||
"success": (Fore.GREEN, "green"),
|
"success": (Fore.GREEN, "green"),
|
||||||
@ -71,22 +64,22 @@ def animate_thinking(text, color="status", duration=2):
|
|||||||
"default": (Fore.RESET, "black"),
|
"default": (Fore.RESET, "black"),
|
||||||
"info": (Fore.CYAN, "cyan")
|
"info": (Fore.CYAN, "cyan")
|
||||||
}
|
}
|
||||||
|
fore_color, term_color = color_map.get(color, color_map["default"])
|
||||||
fore_color, term_color = color_map[color]
|
|
||||||
spinner = itertools.cycle(['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'])
|
spinner = itertools.cycle(['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'])
|
||||||
end_time = time.time() + duration
|
end_time = time.time() + duration
|
||||||
|
|
||||||
while time.time() < end_time:
|
while time.time() < end_time:
|
||||||
symbol = next(spinner)
|
symbol = next(spinner)
|
||||||
if platform.system().lower() != "windows":
|
if platform.system().lower() != "windows":
|
||||||
print(f"\r{fore_color}{symbol} {text}{Fore.RESET}", end="", flush=True)
|
print(f"{fore_color}{symbol} {text}{Fore.RESET}", flush=True)
|
||||||
else:
|
else:
|
||||||
print(colored(f"\r{symbol} {text}", term_color), end="", flush=True)
|
print(colored(f"{symbol} {text}", term_color), flush=True)
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
print("\033[1A\033[K", end="", flush=True)
|
||||||
print()
|
print()
|
||||||
animation_thread = threading.Thread(target=_animate)
|
animation_thread = threading.Thread(target=_animate)
|
||||||
animation_thread.daemon = True
|
|
||||||
animation_thread.start()
|
animation_thread.start()
|
||||||
|
animation_thread.join()
|
||||||
|
|
||||||
def timer_decorator(func):
|
def timer_decorator(func):
|
||||||
"""
|
"""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user