mirror of
https://github.com/tcsenpai/agenticSeek.git
synced 2025-06-06 19:15:28 +00:00
Merge pull request #113 from Fosowl/dev
Router support any language + Java interpreter with fixed lang keyerror
This commit is contained in:
commit
49fab1b488
13
README.md
13
README.md
@ -14,16 +14,8 @@ English | [中文](./README_CHS.md) | [繁體中文](./README_CHT.md) | [Franç
|
|||||||
|
|
||||||
> 🛠️ **Work in Progress** – Looking for contributors!
|
> 🛠️ **Work in Progress** – Looking for contributors!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
https://github.com/user-attachments/assets/fe9e8006-0462-4793-8b31-25bd42c6d1eb
|
https://github.com/user-attachments/assets/fe9e8006-0462-4793-8b31-25bd42c6d1eb
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*And much more!*
|
|
||||||
|
|
||||||
> *Do a deep search of AI startup in Osaka and Tokyo, find at least 5, then save in the research_japan.txt file*
|
> *Do a deep search of AI startup in Osaka and Tokyo, find at least 5, then save in the research_japan.txt file*
|
||||||
|
|
||||||
> *Can you make a tetris game in C ?*
|
> *Can you make a tetris game in C ?*
|
||||||
@ -185,7 +177,7 @@ Here are some example usage:
|
|||||||
|
|
||||||
> *Show me how much space I have left on my disk*
|
> *Show me how much space I have left on my disk*
|
||||||
|
|
||||||
> *Can you install follow the readme and install project at /home/path/project*
|
> *Can you follow the readme and install project at /home/path/project*
|
||||||
|
|
||||||
### Casual
|
### Casual
|
||||||
|
|
||||||
@ -356,6 +348,7 @@ stealth_mode = False
|
|||||||
- listen -> listen to voice input (True) or not (False).
|
- listen -> listen to voice input (True) or not (False).
|
||||||
- work_dir -> Folder the AI will have access to. eg: /Users/user/Documents/.
|
- work_dir -> Folder the AI will have access to. eg: /Users/user/Documents/.
|
||||||
- jarvis_personality -> Uses a JARVIS-like personality (True) or not (False). This simply change the prompt file.
|
- jarvis_personality -> Uses a JARVIS-like personality (True) or not (False). This simply change the prompt file.
|
||||||
|
- languages -> The list of supported language, needed for the llm router to work properly, avoid putting too many or too similar languages.
|
||||||
- headless_browser -> Runs browser without a visible window (True) or not (False).
|
- headless_browser -> Runs browser without a visible window (True) or not (False).
|
||||||
- stealth_mode -> Make bot detector time harder. Only downside is you have to manually install the anticaptcha extension.
|
- stealth_mode -> Make bot detector time harder. Only downside is you have to manually install the anticaptcha extension.
|
||||||
|
|
||||||
@ -445,6 +438,6 @@ We’re looking for developers to improve AgenticSeek! Check out open issues or
|
|||||||
|
|
||||||
[](https://www.star-history.com/#Fosowl/agenticSeek&Date)
|
[](https://www.star-history.com/#Fosowl/agenticSeek&Date)
|
||||||
|
|
||||||
## Authors:
|
## Maintainers:
|
||||||
> [Fosowl](https://github.com/Fosowl)
|
> [Fosowl](https://github.com/Fosowl)
|
||||||
> [steveh8758](https://github.com/steveh8758)
|
> [steveh8758](https://github.com/steveh8758)
|
||||||
|
@ -417,6 +417,6 @@ Nous recherchons des développeurs pour améliorer AgenticSeek ! Consultez la se
|
|||||||
|
|
||||||
[](https://www.star-history.com/#Fosowl/agenticSeek&Date)
|
[](https://www.star-history.com/#Fosowl/agenticSeek&Date)
|
||||||
|
|
||||||
## Auteurs:
|
## Auteurs/Mainteneurs:
|
||||||
> [Fosowl](https://github.com/Fosowl) - Epitech 2024, France
|
> [Fosowl](https://github.com/Fosowl) - Epitech 2024, France
|
||||||
> [steveh8758](https://github.com/steveh8758) - Université Feng Chia, Taiwan
|
> [steveh8758](https://github.com/steveh8758) - Université Feng Chia, Taiwan
|
||||||
|
@ -10,6 +10,7 @@ speak = False
|
|||||||
listen = False
|
listen = False
|
||||||
work_dir = /Users/mlg/Documents/ai_folder
|
work_dir = /Users/mlg/Documents/ai_folder
|
||||||
jarvis_personality = False
|
jarvis_personality = False
|
||||||
|
languages = en zh fr
|
||||||
[BROWSER]
|
[BROWSER]
|
||||||
headless_browser = False
|
headless_browser = False
|
||||||
stealth_mode = False
|
stealth_mode = True
|
7
main.py
7
main.py
@ -18,17 +18,19 @@ config.read('config.ini')
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
pretty_print("Initializing...", color="status")
|
pretty_print("Initializing...", color="status")
|
||||||
|
stealth_mode = config.getboolean('BROWSER', 'stealth_mode')
|
||||||
|
personality_folder = "jarvis" if config.getboolean('MAIN', 'jarvis_personality') else "base"
|
||||||
|
languages = config["MAIN"]["languages"].split(' ')
|
||||||
|
|
||||||
provider = Provider(provider_name=config["MAIN"]["provider_name"],
|
provider = Provider(provider_name=config["MAIN"]["provider_name"],
|
||||||
model=config["MAIN"]["provider_model"],
|
model=config["MAIN"]["provider_model"],
|
||||||
server_address=config["MAIN"]["provider_server_address"],
|
server_address=config["MAIN"]["provider_server_address"],
|
||||||
is_local=config.getboolean('MAIN', 'is_local'))
|
is_local=config.getboolean('MAIN', 'is_local'))
|
||||||
|
|
||||||
stealth_mode = config.getboolean('BROWSER', 'stealth_mode')
|
|
||||||
browser = Browser(
|
browser = Browser(
|
||||||
create_driver(headless=config.getboolean('BROWSER', 'headless_browser'), stealth_mode=stealth_mode),
|
create_driver(headless=config.getboolean('BROWSER', 'headless_browser'), stealth_mode=stealth_mode),
|
||||||
anticaptcha_manual_install=stealth_mode
|
anticaptcha_manual_install=stealth_mode
|
||||||
)
|
)
|
||||||
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"],
|
||||||
@ -52,6 +54,7 @@ def main():
|
|||||||
tts_enabled=config.getboolean('MAIN', 'speak'),
|
tts_enabled=config.getboolean('MAIN', 'speak'),
|
||||||
stt_enabled=config.getboolean('MAIN', 'listen'),
|
stt_enabled=config.getboolean('MAIN', 'listen'),
|
||||||
recover_last_session=config.getboolean('MAIN', 'recover_last_session'),
|
recover_last_session=config.getboolean('MAIN', 'recover_last_session'),
|
||||||
|
langs=languages
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
while interaction.is_active:
|
while interaction.is_active:
|
||||||
|
@ -77,3 +77,4 @@ Rules:
|
|||||||
- Only use web agent for finding necessary informations.
|
- Only use web agent for finding necessary informations.
|
||||||
- If a task might require user email (eg: api services), do not write plan instead ask for user email.
|
- If a task might require user email (eg: api services), do not write plan instead ask for user email.
|
||||||
- Do not search for tutorial.
|
- Do not search for tutorial.
|
||||||
|
- Make sure json is within ```json tag
|
@ -166,6 +166,7 @@ class BrowserAgent(Agent):
|
|||||||
You previously took these notes:
|
You previously took these notes:
|
||||||
{notes}
|
{notes}
|
||||||
Do not Step-by-Step explanation. Write Notes or Error as a long paragraph followed by your action.
|
Do not Step-by-Step explanation. Write Notes or Error as a long paragraph followed by your action.
|
||||||
|
Do not go to tutorials or help pages.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def llm_decide(self, prompt: str, show_reasoning: bool = False) -> Tuple[str, str]:
|
def llm_decide(self, prompt: str, show_reasoning: bool = False) -> Tuple[str, str]:
|
||||||
|
@ -6,6 +6,7 @@ from sources.tools.C_Interpreter import CInterpreter
|
|||||||
from sources.tools.GoInterpreter import GoInterpreter
|
from sources.tools.GoInterpreter import GoInterpreter
|
||||||
from sources.tools.PyInterpreter import PyInterpreter
|
from sources.tools.PyInterpreter import PyInterpreter
|
||||||
from sources.tools.BashInterpreter import BashInterpreter
|
from sources.tools.BashInterpreter import BashInterpreter
|
||||||
|
from sources.tools.JavaInterpreter import JavaInterpreter
|
||||||
from sources.tools.fileFinder import FileFinder
|
from sources.tools.fileFinder import FileFinder
|
||||||
|
|
||||||
class CoderAgent(Agent):
|
class CoderAgent(Agent):
|
||||||
@ -19,6 +20,7 @@ class CoderAgent(Agent):
|
|||||||
"python": PyInterpreter(),
|
"python": PyInterpreter(),
|
||||||
"c": CInterpreter(),
|
"c": CInterpreter(),
|
||||||
"go": GoInterpreter(),
|
"go": GoInterpreter(),
|
||||||
|
"java": JavaInterpreter(),
|
||||||
"file_finder": FileFinder()
|
"file_finder": FileFinder()
|
||||||
}
|
}
|
||||||
self.work_dir = self.tools["file_finder"].get_work_dir()
|
self.work_dir = self.tools["file_finder"].get_work_dir()
|
||||||
|
@ -80,9 +80,10 @@ class PlannerAgent(Agent):
|
|||||||
"""
|
"""
|
||||||
return prompt
|
return prompt
|
||||||
|
|
||||||
def show_plan(self, json_plan: dict) -> None:
|
def show_plan(self, answer: dict) -> None:
|
||||||
agents_tasks = self.parse_agent_tasks(json_plan)
|
agents_tasks = self.parse_agent_tasks(answer)
|
||||||
if agents_tasks == (None, None):
|
if agents_tasks == (None, None):
|
||||||
|
pretty_print(answer, color="warning")
|
||||||
pretty_print("Failed to make a plan. This can happen with (too) small LLM. Clarify your request and insist on it making a plan.", color="failure")
|
pretty_print("Failed to make a plan. This can happen with (too) small LLM. Clarify your request and insist on it making a plan.", color="failure")
|
||||||
return
|
return
|
||||||
pretty_print("\n▂▘ P L A N ▝▂", color="status")
|
pretty_print("\n▂▘ P L A N ▝▂", color="status")
|
||||||
@ -97,10 +98,6 @@ class PlannerAgent(Agent):
|
|||||||
animate_thinking("Thinking...", color="status")
|
animate_thinking("Thinking...", color="status")
|
||||||
self.memory.push('user', prompt)
|
self.memory.push('user', prompt)
|
||||||
answer, _ = self.llm_request()
|
answer, _ = self.llm_request()
|
||||||
for line in answer.split('\n'):
|
|
||||||
if "```json" in line:
|
|
||||||
break
|
|
||||||
pretty_print(line, color="output")
|
|
||||||
self.show_plan(answer)
|
self.show_plan(answer)
|
||||||
ok_str = input("Is the plan ok? (y/n): ")
|
ok_str = input("Is the plan ok? (y/n): ")
|
||||||
if ok_str == 'y':
|
if ok_str == 'y':
|
||||||
|
@ -15,6 +15,7 @@ class Interaction:
|
|||||||
tts_enabled: bool = True,
|
tts_enabled: bool = True,
|
||||||
stt_enabled: bool = True,
|
stt_enabled: bool = True,
|
||||||
recover_last_session: bool = False,
|
recover_last_session: bool = False,
|
||||||
|
langs: List[str] = ["en", "zh"]
|
||||||
):
|
):
|
||||||
self.is_active = True
|
self.is_active = True
|
||||||
self.current_agent = None
|
self.current_agent = None
|
||||||
@ -25,7 +26,7 @@ class Interaction:
|
|||||||
self.tts_enabled = tts_enabled
|
self.tts_enabled = tts_enabled
|
||||||
self.stt_enabled = stt_enabled
|
self.stt_enabled = stt_enabled
|
||||||
self.recover_last_session = recover_last_session
|
self.recover_last_session = recover_last_session
|
||||||
self.router = AgentRouter(self.agents)
|
self.router = AgentRouter(self.agents, supported_language=langs)
|
||||||
if tts_enabled:
|
if tts_enabled:
|
||||||
animate_thinking("Initializing text-to-speech...", color="status")
|
animate_thinking("Initializing text-to-speech...", color="status")
|
||||||
self.speech = Speech(enable=tts_enabled)
|
self.speech = Speech(enable=tts_enabled)
|
||||||
|
@ -10,11 +10,17 @@ from sources.logger import Logger
|
|||||||
|
|
||||||
class LanguageUtility:
|
class LanguageUtility:
|
||||||
"""LanguageUtility for language, or emotion identification"""
|
"""LanguageUtility for language, or emotion identification"""
|
||||||
def __init__(self):
|
def __init__(self, supported_language: List[str] = ["en", "fr", "zh"]):
|
||||||
|
"""
|
||||||
|
Initialize the LanguageUtility class
|
||||||
|
args:
|
||||||
|
supported_language: list of languages for translation, determine which Helsinki-NLP model to load
|
||||||
|
"""
|
||||||
self.sid = None
|
self.sid = None
|
||||||
self.translators_tokenizer = None
|
self.translators_tokenizer = None
|
||||||
self.translators_model = None
|
self.translators_model = None
|
||||||
self.logger = Logger("language.log")
|
self.logger = Logger("language.log")
|
||||||
|
self.supported_language = supported_language
|
||||||
self.load_model()
|
self.load_model()
|
||||||
|
|
||||||
def load_model(self) -> None:
|
def load_model(self) -> None:
|
||||||
@ -24,23 +30,18 @@ class LanguageUtility:
|
|||||||
except LookupError:
|
except LookupError:
|
||||||
nltk.download('vader_lexicon')
|
nltk.download('vader_lexicon')
|
||||||
self.sid = SentimentIntensityAnalyzer()
|
self.sid = SentimentIntensityAnalyzer()
|
||||||
self.translators_tokenizer = {
|
self.translators_tokenizer = {lang: MarianTokenizer.from_pretrained(f"Helsinki-NLP/opus-mt-{lang}-en") for lang in self.supported_language if lang != "en"}
|
||||||
"fr": MarianTokenizer.from_pretrained("Helsinki-NLP/opus-mt-fr-en"),
|
self.translators_model = {lang: MarianMTModel.from_pretrained(f"Helsinki-NLP/opus-mt-{lang}-en") for lang in self.supported_language if lang != "en"}
|
||||||
"zh": MarianTokenizer.from_pretrained("Helsinki-NLP/opus-mt-zh-en")
|
|
||||||
}
|
|
||||||
self.translators_model = {
|
|
||||||
"fr": MarianMTModel.from_pretrained("Helsinki-NLP/opus-mt-fr-en"),
|
|
||||||
"zh": MarianMTModel.from_pretrained("Helsinki-NLP/opus-mt-zh-en")
|
|
||||||
}
|
|
||||||
|
|
||||||
def detect_language(self, text: str) -> str:
|
def detect_language(self, text: str) -> str:
|
||||||
"""
|
"""
|
||||||
Detect the language of the given text using langdetect
|
Detect the language of the given text using langdetect
|
||||||
|
Limited to the supported languages list because of the model tendency to mistake similar languages
|
||||||
Args:
|
Args:
|
||||||
text: string to analyze
|
text: string to analyze
|
||||||
Returns: ISO639-1 language code
|
Returns: ISO639-1 language code
|
||||||
"""
|
"""
|
||||||
langid.set_languages(['fr', 'en', 'zh'])
|
langid.set_languages(self.supported_language)
|
||||||
lang, score = langid.classify(text)
|
lang, score = langid.classify(text)
|
||||||
self.logger.info(f"Identified: {text} as {lang} with conf {score}")
|
self.logger.info(f"Identified: {text} as {lang} with conf {score}")
|
||||||
return lang
|
return lang
|
||||||
|
@ -20,10 +20,10 @@ class AgentRouter:
|
|||||||
"""
|
"""
|
||||||
AgentRouter is a class that selects the appropriate agent based on the user query.
|
AgentRouter is a class that selects the appropriate agent based on the user query.
|
||||||
"""
|
"""
|
||||||
def __init__(self, agents: list):
|
def __init__(self, agents: list, supported_language: List[str] = ["en", "fr", "zh"]):
|
||||||
self.agents = agents
|
self.agents = agents
|
||||||
self.logger = Logger("router.log")
|
self.logger = Logger("router.log")
|
||||||
self.lang_analysis = LanguageUtility()
|
self.lang_analysis = LanguageUtility(supported_language=supported_language)
|
||||||
self.pipelines = self.load_pipelines()
|
self.pipelines = self.load_pipelines()
|
||||||
self.talk_classifier = self.load_llm_router()
|
self.talk_classifier = self.load_llm_router()
|
||||||
self.complexity_classifier = self.load_llm_router()
|
self.complexity_classifier = self.load_llm_router()
|
||||||
@ -100,10 +100,17 @@ class AgentRouter:
|
|||||||
("could you check if the presentation.pdf file exists in my downloads?", "LOW"),
|
("could you check if the presentation.pdf file exists in my downloads?", "LOW"),
|
||||||
("search my drive for a file called vacation_photos_2023.jpg.", "LOW"),
|
("search my drive for a file called vacation_photos_2023.jpg.", "LOW"),
|
||||||
("help me organize my desktop files into folders by type.", "LOW"),
|
("help me organize my desktop files into folders by type.", "LOW"),
|
||||||
|
("make a blackjack in golang", "LOW"),
|
||||||
|
("write a python script to ping a website", "LOW"),
|
||||||
|
("write a simple Java program to print 'Hello World'", "LOW"),
|
||||||
|
("write a Java program to calculate the area of a circle", "LOW"),
|
||||||
("write a Python function to sort a list of dictionaries by key", "LOW"),
|
("write a Python function to sort a list of dictionaries by key", "LOW"),
|
||||||
("can you search for startup in tokyo?", "LOW"),
|
("can you search for startup in tokyo?", "LOW"),
|
||||||
("find the latest updates on quantum computing on the web", "LOW"),
|
("find the latest updates on quantum computing on the web", "LOW"),
|
||||||
("check if the folder ‘Work_Projects’ exists on my desktop", "LOW"),
|
("check if the folder ‘Work_Projects’ exists on my desktop", "LOW"),
|
||||||
|
(" can you browse the web, use overpass-turbo to show fountains in toulouse", "LOW"),
|
||||||
|
("search the web for the best budget smartphones of 2025", "LOW"),
|
||||||
|
("write a Python script to download all images from a webpage", "LOW"),
|
||||||
("create a bash script to monitor CPU usage", "LOW"),
|
("create a bash script to monitor CPU usage", "LOW"),
|
||||||
("debug this C++ code that keeps crashing", "LOW"),
|
("debug this C++ code that keeps crashing", "LOW"),
|
||||||
("can you browse the web to find out who fosowl is ?", "LOW"),
|
("can you browse the web to find out who fosowl is ?", "LOW"),
|
||||||
@ -153,8 +160,10 @@ class AgentRouter:
|
|||||||
("Find the latest research on renewable energy and build a web app to display it", "HIGH"),
|
("Find the latest research on renewable energy and build a web app to display it", "HIGH"),
|
||||||
("can you find vitess repo, clone it and install by following the readme", "HIGH"),
|
("can you find vitess repo, clone it and install by following the readme", "HIGH"),
|
||||||
("Create a JavaScript game using Phaser.js with multiple levels", "HIGH"),
|
("Create a JavaScript game using Phaser.js with multiple levels", "HIGH"),
|
||||||
|
("Search the web for the latest trends in web development and build a sample site", "HIGH"),
|
||||||
("Use my research_note.txt file, double check the informations on the web", "HIGH"),
|
("Use my research_note.txt file, double check the informations on the web", "HIGH"),
|
||||||
("Make a web server in go that query a flight API and display them in a app", "HIGH"),
|
("Make a web server in go that query a flight API and display them in a app", "HIGH"),
|
||||||
|
("Search the web for the latest trends in AI and demo it in pytorch", "HIGH"),
|
||||||
("can you lookup for api that track flight and build a web flight tracking app", "HIGH"),
|
("can you lookup for api that track flight and build a web flight tracking app", "HIGH"),
|
||||||
("Find the file toto.pdf then use its content to reply to Jojo on superforum.com", "HIGH"),
|
("Find the file toto.pdf then use its content to reply to Jojo on superforum.com", "HIGH"),
|
||||||
("Create a whole web app in python using the flask framework that query news API", "HIGH"),
|
("Create a whole web app in python using the flask framework that query news API", "HIGH"),
|
||||||
@ -421,7 +430,8 @@ class AgentRouter:
|
|||||||
Returns:
|
Returns:
|
||||||
Agent: The selected agent
|
Agent: The selected agent
|
||||||
"""
|
"""
|
||||||
if len(self.agents) == 0:
|
assert len(self.agents) > 0, "No agents available."
|
||||||
|
if len(self.agents) == 1:
|
||||||
return self.agents[0]
|
return self.agents[0]
|
||||||
lang = self.lang_analysis.detect_language(text)
|
lang = self.lang_analysis.detect_language(text)
|
||||||
text = self.find_first_sentence(text)
|
text = self.find_first_sentence(text)
|
||||||
@ -440,7 +450,8 @@ class AgentRouter:
|
|||||||
raise e
|
raise e
|
||||||
for agent in self.agents:
|
for agent in self.agents:
|
||||||
if best_agent == agent.role["en"]:
|
if best_agent == agent.role["en"]:
|
||||||
pretty_print(f"Selected agent: {agent.agent_name} (roles: {agent.role[lang]})", color="warning")
|
role_name = agent.role[lang] if lang in agent.role else agent.role["en"]
|
||||||
|
pretty_print(f"Selected agent: {agent.agent_name} (roles: {role_name})", color="warning")
|
||||||
return agent
|
return agent
|
||||||
pretty_print(f"Error choosing agent.", color="failure")
|
pretty_print(f"Error choosing agent.", color="failure")
|
||||||
self.logger.error("No agent selected.")
|
self.logger.error("No agent selected.")
|
||||||
|
@ -25,7 +25,7 @@ class BashInterpreter(Tools):
|
|||||||
If so, return True, otherwise return False.
|
If so, return True, otherwise return False.
|
||||||
Code written by the AI will be executed automatically, 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++", "mvn", "go", "javac", "rustc", "clang", "clang++", "rustc", "rustc++", "rustc++"]
|
||||||
for word in command.split():
|
for word in command.split():
|
||||||
if word in lang_interpreter:
|
if word in lang_interpreter:
|
||||||
return True
|
return True
|
||||||
@ -44,7 +44,7 @@ class BashInterpreter(Tools):
|
|||||||
command = command.replace('\n', '')
|
command = command.replace('\n', '')
|
||||||
if self.safe_mode and is_unsafe(commands):
|
if self.safe_mode and is_unsafe(commands):
|
||||||
return "Unsafe command detected, execution aborted."
|
return "Unsafe command detected, execution aborted."
|
||||||
if self.language_bash_attempt(command) and allow_language_exec_bash == False:
|
if self.language_bash_attempt(command) and self.allow_language_exec_bash == False:
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
process = subprocess.Popen(
|
process = subprocess.Popen(
|
||||||
|
184
sources/tools/JavaInterpreter.py
Normal file
184
sources/tools/JavaInterpreter.py
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
import subprocess
|
||||||
|
import os
|
||||||
|
import tempfile
|
||||||
|
import re
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
from tools import Tools
|
||||||
|
else:
|
||||||
|
from sources.tools.tools import Tools
|
||||||
|
|
||||||
|
class JavaInterpreter(Tools):
|
||||||
|
"""
|
||||||
|
This class is a tool to allow execution of Java code.
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.tag = "java"
|
||||||
|
|
||||||
|
def execute(self, codes: str, safety=False) -> str:
|
||||||
|
"""
|
||||||
|
Execute Java code by compiling and running it.
|
||||||
|
"""
|
||||||
|
output = ""
|
||||||
|
code = '\n'.join(codes) if isinstance(codes, list) else codes
|
||||||
|
|
||||||
|
if safety and input("Execute code? y/n ") != "y":
|
||||||
|
return "Code rejected by user."
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||||
|
source_file = os.path.join(tmpdirname, "Main.java")
|
||||||
|
class_dir = tmpdirname
|
||||||
|
with open(source_file, 'w') as f:
|
||||||
|
f.write(code)
|
||||||
|
|
||||||
|
try:
|
||||||
|
compile_command = ["javac", "-d", class_dir, source_file]
|
||||||
|
compile_result = subprocess.run(
|
||||||
|
compile_command,
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=10
|
||||||
|
)
|
||||||
|
|
||||||
|
if compile_result.returncode != 0:
|
||||||
|
return f"Compilation failed: {compile_result.stderr}"
|
||||||
|
|
||||||
|
run_command = ["java", "-cp", class_dir, "Main"]
|
||||||
|
run_result = subprocess.run(
|
||||||
|
run_command,
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=10
|
||||||
|
)
|
||||||
|
|
||||||
|
if run_result.returncode != 0:
|
||||||
|
return f"Execution failed: {run_result.stderr}"
|
||||||
|
output = run_result.stdout
|
||||||
|
|
||||||
|
except subprocess.TimeoutExpired as e:
|
||||||
|
return f"Execution timed out: {str(e)}"
|
||||||
|
except FileNotFoundError:
|
||||||
|
return "Error: 'java' or 'javac' not found. Ensure Java is installed and in PATH."
|
||||||
|
except Exception as e:
|
||||||
|
return f"Code execution failed: {str(e)}"
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
def interpreter_feedback(self, output: str) -> str:
|
||||||
|
"""
|
||||||
|
Provide feedback based on the output of the code execution.
|
||||||
|
"""
|
||||||
|
if self.execution_failure_check(output):
|
||||||
|
feedback = f"[failure] Error in execution:\n{output}"
|
||||||
|
else:
|
||||||
|
feedback = "[success] Execution success, code output:\n" + output
|
||||||
|
return feedback
|
||||||
|
|
||||||
|
def execution_failure_check(self, feedback: str) -> bool:
|
||||||
|
"""
|
||||||
|
Check if the code execution failed.
|
||||||
|
"""
|
||||||
|
error_patterns = [
|
||||||
|
r"error",
|
||||||
|
r"failed",
|
||||||
|
r"exception",
|
||||||
|
r"invalid",
|
||||||
|
r"syntax",
|
||||||
|
r"cannot",
|
||||||
|
r"stack trace",
|
||||||
|
r"unresolved",
|
||||||
|
r"not found"
|
||||||
|
]
|
||||||
|
combined_pattern = "|".join(error_patterns)
|
||||||
|
if re.search(combined_pattern, feedback, re.IGNORECASE):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
codes = [
|
||||||
|
"""
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
|
||||||
|
public class Main extends JPanel {
|
||||||
|
private double[][] vertices = {
|
||||||
|
{-1, -1, -1}, {1, -1, -1}, {1, 1, -1}, {-1, 1, -1}, // Back face
|
||||||
|
{-1, -1, 1}, {1, -1, 1}, {1, 1, 1}, {-1, 1, 1} // Front face
|
||||||
|
};
|
||||||
|
private int[][] edges = {
|
||||||
|
{0, 1}, {1, 2}, {2, 3}, {3, 0}, // Back face
|
||||||
|
{4, 5}, {5, 6}, {6, 7}, {7, 4}, // Front face
|
||||||
|
{0, 4}, {1, 5}, {2, 6}, {3, 7} // Connecting edges
|
||||||
|
};
|
||||||
|
private double angleX = 0, angleY = 0;
|
||||||
|
private final double scale = 100;
|
||||||
|
private final double distance = 5;
|
||||||
|
|
||||||
|
public Main() {
|
||||||
|
Timer timer = new Timer(50, new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
angleX += 0.03;
|
||||||
|
angleY += 0.05;
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
timer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintComponent(Graphics g) {
|
||||||
|
super.paintComponent(g);
|
||||||
|
Graphics2D g2d = (Graphics2D) g;
|
||||||
|
g2d.setColor(Color.BLACK);
|
||||||
|
g2d.fillRect(0, 0, getWidth(), getHeight());
|
||||||
|
g2d.setColor(Color.WHITE);
|
||||||
|
|
||||||
|
double[][] projected = new double[vertices.length][2];
|
||||||
|
for (int i = 0; i < vertices.length; i++) {
|
||||||
|
double x = vertices[i][0];
|
||||||
|
double y = vertices[i][1];
|
||||||
|
double z = vertices[i][2];
|
||||||
|
|
||||||
|
// Rotate around X-axis
|
||||||
|
double y1 = y * Math.cos(angleX) - z * Math.sin(angleX);
|
||||||
|
double z1 = y * Math.sin(angleX) + z * Math.cos(angleX);
|
||||||
|
|
||||||
|
// Rotate around Y-axis
|
||||||
|
double x1 = x * Math.cos(angleY) + z1 * Math.sin(angleY);
|
||||||
|
double z2 = -x * Math.sin(angleY) + z1 * Math.cos(angleY);
|
||||||
|
|
||||||
|
// Perspective projection
|
||||||
|
double factor = distance / (distance + z2);
|
||||||
|
double px = x1 * factor * scale;
|
||||||
|
double py = y1 * factor * scale;
|
||||||
|
|
||||||
|
projected[i][0] = px + getWidth() / 2;
|
||||||
|
projected[i][1] = py + getHeight() / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw edges
|
||||||
|
for (int[] edge : edges) {
|
||||||
|
int x1 = (int) projected[edge[0]][0];
|
||||||
|
int y1 = (int) projected[edge[0]][1];
|
||||||
|
int x2 = (int) projected[edge[1]][0];
|
||||||
|
int y2 = (int) projected[edge[1]][1];
|
||||||
|
g2d.drawLine(x1, y1, x2, y2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
JFrame frame = new JFrame("Rotating 3D Cube");
|
||||||
|
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
frame.setSize(400, 400);
|
||||||
|
frame.add(new Main());
|
||||||
|
frame.setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
]
|
||||||
|
j = JavaInterpreter()
|
||||||
|
print(j.execute(codes))
|
Loading…
x
Reference in New Issue
Block a user