codeaois 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- codeaois/__init__.py +0 -0
- codeaois/agents/3d_agent.py +23 -0
- codeaois/agents/coder_agent.py +25 -0
- codeaois/agents/data_science_agent.py +24 -0
- codeaois/agents/database_agent.py +23 -0
- codeaois/agents/debugging_agent.py +23 -0
- codeaois/agents/devops_agent.py +23 -0
- codeaois/agents/git_agent.py +45 -0
- codeaois/agents/tester_agent.py +27 -0
- codeaois/app.py +1 -0
- codeaois/brain/__init__.py +0 -0
- codeaois/brain/embeddings.py +27 -0
- codeaois/brain/memory.py +10 -0
- codeaois/brain/scanner.py +49 -0
- codeaois/cli/__init__.py +0 -0
- codeaois/cli/main.py +351 -0
- codeaois/config/settings.py +0 -0
- codeaois/core/context.py +39 -0
- codeaois/core/marketplace.py +65 -0
- codeaois/core/memory.py +65 -0
- codeaois/core/orchestrator.py +23 -0
- codeaois/core/planner.py +51 -0
- codeaois/core/router.py +6 -0
- codeaois/models/llm_interface.py +89 -0
- codeaois/utils/file_writer.py +65 -0
- codeaois/utils/logger.py +5 -0
- codeaois-0.1.0.dist-info/METADATA +232 -0
- codeaois-0.1.0.dist-info/RECORD +31 -0
- codeaois-0.1.0.dist-info/WHEEL +5 -0
- codeaois-0.1.0.dist-info/entry_points.txt +2 -0
- codeaois-0.1.0.dist-info/top_level.txt +1 -0
codeaois/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# codeaois/agents/3d_agent.py
|
|
2
|
+
from codeaois.models.llm_interface import call_openrouter
|
|
3
|
+
|
|
4
|
+
def generate_3d_code(user_prompt: str, file_context: str = "") -> str:
|
|
5
|
+
"""Specialized 3D Agent worker."""
|
|
6
|
+
system_prompt = (
|
|
7
|
+
"You are the CodeAOIS 3D Agent. "
|
|
8
|
+
"Your job is to provide highly optimized, expert-level code strictly for your specific domain. "
|
|
9
|
+
"CRITICAL: Output ONLY the raw, complete code. Do not wrap the code in markdown blocks."
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
full_prompt = user_prompt
|
|
13
|
+
if file_context:
|
|
14
|
+
full_prompt += f"\n\nHere are the existing files for context:\n{file_context}"
|
|
15
|
+
|
|
16
|
+
response = call_openrouter(system_prompt, full_prompt)
|
|
17
|
+
|
|
18
|
+
if response.startswith("```"):
|
|
19
|
+
lines = response.split("\n")
|
|
20
|
+
if len(lines) > 2:
|
|
21
|
+
response = "\n".join(lines[1:-1])
|
|
22
|
+
|
|
23
|
+
return response.strip()
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# codeaois/agents/coder_agent.py
|
|
2
|
+
from codeaois.models.llm_interface import call_openrouter
|
|
3
|
+
|
|
4
|
+
def generate_code(user_prompt: str, file_context: str = "") -> str:
|
|
5
|
+
if file_context:
|
|
6
|
+
system_prompt = (
|
|
7
|
+
"You are the CodeAOIS Coder Agent. "
|
|
8
|
+
"1. You MUST output your code changes using the <<<<<<< SEARCH and >>>>>>> REPLACE format.\n"
|
|
9
|
+
"2. AFTER your code blocks, you MUST add the exact text '---SUMMARY---' on a new line.\n"
|
|
10
|
+
"3. AFTER the summary delimiter, write a brief, friendly explanation of how the code works and what you changed."
|
|
11
|
+
)
|
|
12
|
+
else:
|
|
13
|
+
system_prompt = (
|
|
14
|
+
"You are the CodeAOIS Coder Agent, an expert senior software engineer. "
|
|
15
|
+
"1. Output the raw, complete code first. Do not wrap the code in markdown blocks.\n"
|
|
16
|
+
"2. AFTER the code, you MUST add the exact text '---SUMMARY---' on a new line.\n"
|
|
17
|
+
"3. AFTER the summary delimiter, write a brief, friendly explanation of how the code works."
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
full_prompt = user_prompt
|
|
21
|
+
if file_context:
|
|
22
|
+
full_prompt += f"\n\nHere are the existing files for context:\n{file_context}"
|
|
23
|
+
|
|
24
|
+
response = call_openrouter(system_prompt, full_prompt, intent="code")
|
|
25
|
+
return response.strip()
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# codeaois/agents/data_science_agent.py
|
|
2
|
+
from codeaois.models.llm_interface import call_openrouter
|
|
3
|
+
|
|
4
|
+
def generate_ds_code(user_prompt: str, file_context: str = "") -> str:
|
|
5
|
+
system_prompt = (
|
|
6
|
+
"You are the CodeAOIS Data Science Agent, an elite data scientist and Python developer. "
|
|
7
|
+
"Your job is to provide highly optimized, memory-efficient code for data manipulation, "
|
|
8
|
+
"analysis, and visualization. "
|
|
9
|
+
"CRITICAL: Output ONLY the raw, complete code. Do not wrap the code in markdown blocks."
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
full_prompt = user_prompt
|
|
13
|
+
if file_context:
|
|
14
|
+
full_prompt += f"\n\nHere are the existing files for context. Modify as requested:\n{file_context}"
|
|
15
|
+
|
|
16
|
+
# Pass the data_science intent to trigger the Qwen/Step model list
|
|
17
|
+
response = call_openrouter(system_prompt, full_prompt, intent="data_science")
|
|
18
|
+
|
|
19
|
+
if response.startswith("```"):
|
|
20
|
+
lines = response.split("\n")
|
|
21
|
+
if len(lines) > 2:
|
|
22
|
+
response = "\n".join(lines[1:-1])
|
|
23
|
+
|
|
24
|
+
return response.strip()
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# codeaois/agents/database_agent.py
|
|
2
|
+
from codeaois.models.llm_interface import call_openrouter
|
|
3
|
+
|
|
4
|
+
def generate_database_code(user_prompt: str, file_context: str = "") -> str:
|
|
5
|
+
"""Specialized Database Agent worker."""
|
|
6
|
+
system_prompt = (
|
|
7
|
+
"You are the CodeAOIS Database Agent. "
|
|
8
|
+
"Your job is to provide highly optimized, expert-level code strictly for your specific domain. "
|
|
9
|
+
"CRITICAL: Output ONLY the raw, complete code. Do not wrap the code in markdown blocks."
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
full_prompt = user_prompt
|
|
13
|
+
if file_context:
|
|
14
|
+
full_prompt += f"\n\nHere are the existing files for context:\n{file_context}"
|
|
15
|
+
|
|
16
|
+
response = call_openrouter(system_prompt, full_prompt)
|
|
17
|
+
|
|
18
|
+
if response.startswith("```"):
|
|
19
|
+
lines = response.split("\n")
|
|
20
|
+
if len(lines) > 2:
|
|
21
|
+
response = "\n".join(lines[1:-1])
|
|
22
|
+
|
|
23
|
+
return response.strip()
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# codeaois/agents/debugging_agent.py
|
|
2
|
+
from codeaois.models.llm_interface import call_openrouter
|
|
3
|
+
|
|
4
|
+
def generate_debugging_code(user_prompt: str, file_context: str = "") -> str:
|
|
5
|
+
"""Specialized Debugging Agent worker."""
|
|
6
|
+
system_prompt = (
|
|
7
|
+
"You are the CodeAOIS Debugging Agent. "
|
|
8
|
+
"Your job is to provide highly optimized, expert-level code strictly for your specific domain. "
|
|
9
|
+
"CRITICAL: Output ONLY the raw, complete code. Do not wrap the code in markdown blocks."
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
full_prompt = user_prompt
|
|
13
|
+
if file_context:
|
|
14
|
+
full_prompt += f"\n\nHere are the existing files for context:\n{file_context}"
|
|
15
|
+
|
|
16
|
+
response = call_openrouter(system_prompt, full_prompt)
|
|
17
|
+
|
|
18
|
+
if response.startswith("```"):
|
|
19
|
+
lines = response.split("\n")
|
|
20
|
+
if len(lines) > 2:
|
|
21
|
+
response = "\n".join(lines[1:-1])
|
|
22
|
+
|
|
23
|
+
return response.strip()
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# codeaois/agents/devops_agent.py
|
|
2
|
+
from codeaois.models.llm_interface import call_openrouter
|
|
3
|
+
|
|
4
|
+
def generate_devops_code(user_prompt: str, file_context: str = "") -> str:
|
|
5
|
+
"""Specialized Devops Agent worker."""
|
|
6
|
+
system_prompt = (
|
|
7
|
+
"You are the CodeAOIS Devops Agent. "
|
|
8
|
+
"Your job is to provide highly optimized, expert-level code strictly for your specific domain. "
|
|
9
|
+
"CRITICAL: Output ONLY the raw, complete code. Do not wrap the code in markdown blocks."
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
full_prompt = user_prompt
|
|
13
|
+
if file_context:
|
|
14
|
+
full_prompt += f"\n\nHere are the existing files for context:\n{file_context}"
|
|
15
|
+
|
|
16
|
+
response = call_openrouter(system_prompt, full_prompt)
|
|
17
|
+
|
|
18
|
+
if response.startswith("```"):
|
|
19
|
+
lines = response.split("\n")
|
|
20
|
+
if len(lines) > 2:
|
|
21
|
+
response = "\n".join(lines[1:-1])
|
|
22
|
+
|
|
23
|
+
return response.strip()
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# codeaois/agents/git_agent.py
|
|
2
|
+
import subprocess
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
C_YELLOW = '\033[93m'
|
|
6
|
+
C_GREEN = '\033[92m'
|
|
7
|
+
C_RESET = '\033[0m'
|
|
8
|
+
|
|
9
|
+
def run_git_command(command: list) -> tuple[bool, str]:
|
|
10
|
+
"""Quietly executes a terminal command and returns the result."""
|
|
11
|
+
try:
|
|
12
|
+
result = subprocess.run(command, capture_output=True, text=True, check=True)
|
|
13
|
+
return True, result.stdout.strip()
|
|
14
|
+
except subprocess.CalledProcessError as e:
|
|
15
|
+
return False, e.stderr.strip()
|
|
16
|
+
|
|
17
|
+
def auto_commit(file_path: str, message: str):
|
|
18
|
+
"""Automatically stages and commits a modified file."""
|
|
19
|
+
|
|
20
|
+
# 1. Check if the user is inside a Git repository
|
|
21
|
+
is_git, _ = run_git_command(["git", "rev-parse", "--is-inside-work-tree"])
|
|
22
|
+
if not is_git:
|
|
23
|
+
print(f" {C_YELLOW}โ ๏ธ [Git Agent] No .git repository found in this folder. Skipping auto-commit.{C_RESET}")
|
|
24
|
+
return
|
|
25
|
+
|
|
26
|
+
print(f" {C_GREEN}๐ฟ [Git Agent] Engaging version control...{C_RESET}")
|
|
27
|
+
|
|
28
|
+
# 2. Stage only the specific file the AI just modified
|
|
29
|
+
success, err = run_git_command(["git", "add", file_path])
|
|
30
|
+
if not success:
|
|
31
|
+
print(f" {C_YELLOW}โ ๏ธ [Git Agent] Failed to stage file: {err}{C_RESET}")
|
|
32
|
+
return
|
|
33
|
+
|
|
34
|
+
# 3. Double-check that there are actually changes to save
|
|
35
|
+
has_changes, diff = run_git_command(["git", "status", "--porcelain"])
|
|
36
|
+
if not has_changes or not diff:
|
|
37
|
+
print(f" {C_YELLOW}โ ๏ธ [Git Agent] No actual code changes detected for {file_path}.{C_RESET}")
|
|
38
|
+
return
|
|
39
|
+
|
|
40
|
+
# 4. Commit the changes to the timeline
|
|
41
|
+
commit_success, commit_err = run_git_command(["git", "commit", "-m", message])
|
|
42
|
+
if commit_success:
|
|
43
|
+
print(f" {C_GREEN}โ
[Git Agent] Successfully committed changes to {file_path}!{C_RESET}")
|
|
44
|
+
else:
|
|
45
|
+
print(f" {C_YELLOW}โ ๏ธ [Git Agent] Commit failed: {commit_err}{C_RESET}")
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# codeaois/agents/tester_agent.py
|
|
2
|
+
import subprocess
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
def run_test(file_path: str) -> tuple[bool, str]:
|
|
6
|
+
"""Runs a Python script and catches any terminal errors."""
|
|
7
|
+
if not file_path.endswith('.py'):
|
|
8
|
+
return True, "Not a Python file. Skipping auto-test."
|
|
9
|
+
|
|
10
|
+
try:
|
|
11
|
+
# sys.executable ensures it uses your isolated 'venv' Python, not the global Ubuntu one!
|
|
12
|
+
result = subprocess.run(
|
|
13
|
+
[sys.executable, file_path],
|
|
14
|
+
capture_output=True,
|
|
15
|
+
text=True,
|
|
16
|
+
timeout=10 # 10-second kill switch so infinite loops don't crash your computer
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
if result.returncode == 0:
|
|
20
|
+
return True, result.stdout.strip()
|
|
21
|
+
else:
|
|
22
|
+
return False, result.stderr.strip()
|
|
23
|
+
|
|
24
|
+
except subprocess.TimeoutExpired:
|
|
25
|
+
return False, "Error: Script execution timed out (possible infinite loop)."
|
|
26
|
+
except Exception as e:
|
|
27
|
+
return False, str(e)
|
codeaois/app.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# AI-generated code for: Modify `app.py` with instruction: create Flask API, preserving style and existing code
|
|
File without changes
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import numpy as np
|
|
3
|
+
from sentence_transformers import SentenceTransformer
|
|
4
|
+
|
|
5
|
+
# Lightweight model for semantic search
|
|
6
|
+
model = SentenceTransformer("all-MiniLM-L6-v2")
|
|
7
|
+
|
|
8
|
+
class ProjectEmbeddings:
|
|
9
|
+
def __init__(self):
|
|
10
|
+
self.index = {} # {filepath: embedding}
|
|
11
|
+
|
|
12
|
+
def build_index(self, project_path="."):
|
|
13
|
+
for root, dirs, files in os.walk(project_path):
|
|
14
|
+
dirs[:] = [d for d in dirs if d not in {"aois_env", ".git", "__pycache__", "node_modules"}]
|
|
15
|
+
for f in files:
|
|
16
|
+
if f.endswith(".py"):
|
|
17
|
+
path = os.path.join(root, f)
|
|
18
|
+
with open(path, "r", encoding="utf-8") as file:
|
|
19
|
+
content = file.read()
|
|
20
|
+
embedding = model.encode(content)
|
|
21
|
+
self.index[path] = embedding
|
|
22
|
+
|
|
23
|
+
def search(self, query, top_k=3):
|
|
24
|
+
q_vec = model.encode(query)
|
|
25
|
+
distances = [(f, np.dot(q_vec, emb)) for f, emb in self.index.items()]
|
|
26
|
+
distances.sort(key=lambda x: x[1], reverse=True)
|
|
27
|
+
return distances[:top_k]
|
codeaois/brain/memory.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# codeaois/brain/scanner.py
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
def scan_project_structure(root_dir: str = ".", ignore_dirs: list = None, max_depth: int = 3, max_files: int = 200) -> str:
|
|
5
|
+
"""
|
|
6
|
+
Goal #9: Project Brain (with safety limits).
|
|
7
|
+
Scans the folder structure but strictly limits depth and file count
|
|
8
|
+
to prevent network timeouts when run in massive directories like '~'.
|
|
9
|
+
"""
|
|
10
|
+
if ignore_dirs is None:
|
|
11
|
+
# Added OS-level hidden folders to ignore list
|
|
12
|
+
ignore_dirs = ['.git', '__pycache__', 'venv', 'env', 'node_modules', '.venv', 'codeaois.egg-info', '.cache', '.config', '.local']
|
|
13
|
+
|
|
14
|
+
tree_str = f"๐ Project Root: {os.path.abspath(root_dir)}\n"
|
|
15
|
+
file_count = 0
|
|
16
|
+
|
|
17
|
+
# Calculate starting depth
|
|
18
|
+
start_level = root_dir.rstrip(os.sep).count(os.sep)
|
|
19
|
+
|
|
20
|
+
for dirpath, dirnames, filenames in os.walk(root_dir):
|
|
21
|
+
# Calculate current depth relative to start
|
|
22
|
+
current_level = dirpath.rstrip(os.sep).count(os.sep)
|
|
23
|
+
level = current_level - start_level
|
|
24
|
+
|
|
25
|
+
# Stop digging if we hit our depth limit
|
|
26
|
+
if level > max_depth:
|
|
27
|
+
dirnames[:] = [] # Clear the list to stop os.walk from going deeper
|
|
28
|
+
continue
|
|
29
|
+
|
|
30
|
+
dirnames[:] = [d for d in dirnames if d not in ignore_dirs and not d.startswith('.')]
|
|
31
|
+
|
|
32
|
+
indent = ' ' * 4 * level
|
|
33
|
+
folder_name = os.path.basename(dirpath)
|
|
34
|
+
|
|
35
|
+
if level > 0:
|
|
36
|
+
tree_str += f"{indent}๐ {folder_name}/\n"
|
|
37
|
+
|
|
38
|
+
sub_indent = ' ' * 4 * (level + 1)
|
|
39
|
+
for f in filenames:
|
|
40
|
+
# Emergency Stop: Prevent massive payloads from timing out the API
|
|
41
|
+
if file_count >= max_files:
|
|
42
|
+
tree_str += f"{sub_indent}... [Max file limit reached to protect API connection]\n"
|
|
43
|
+
return tree_str
|
|
44
|
+
|
|
45
|
+
if f != '.env' and not f.startswith('.'):
|
|
46
|
+
tree_str += f"{sub_indent}๐ {f}\n"
|
|
47
|
+
file_count += 1
|
|
48
|
+
|
|
49
|
+
return tree_str
|
codeaois/cli/__init__.py
ADDED
|
File without changes
|
codeaois/cli/main.py
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
# codeaois/cli/main.py
|
|
2
|
+
import argparse
|
|
3
|
+
import sys
|
|
4
|
+
import os
|
|
5
|
+
import importlib
|
|
6
|
+
|
|
7
|
+
# --- CLI UI ENGINES ---
|
|
8
|
+
from prompt_toolkit import PromptSession
|
|
9
|
+
from prompt_toolkit.completion import WordCompleter
|
|
10
|
+
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
|
|
11
|
+
from prompt_toolkit.formatted_text import HTML
|
|
12
|
+
from rich.console import Console
|
|
13
|
+
from rich.markdown import Markdown
|
|
14
|
+
from rich.panel import Panel
|
|
15
|
+
from rich.table import Table # <-- ADD THIS!
|
|
16
|
+
|
|
17
|
+
# --- CODEAOIS MODULES ---
|
|
18
|
+
from codeaois.core.planner import analyze_intent, get_installed_agents
|
|
19
|
+
from codeaois.core.context import extract_file_context
|
|
20
|
+
from codeaois.brain.scanner import scan_project_structure
|
|
21
|
+
from codeaois.models.llm_interface import call_openrouter
|
|
22
|
+
from codeaois.agents.coder_agent import generate_code
|
|
23
|
+
from codeaois.agents.data_science_agent import generate_ds_code
|
|
24
|
+
from codeaois.utils.file_writer import extract_and_save_code
|
|
25
|
+
from codeaois.agents.git_agent import auto_commit
|
|
26
|
+
from codeaois.core.marketplace import install_agent
|
|
27
|
+
from codeaois.core.memory import load_profile, create_profile, load_history, save_history, clear_history_data, clear_profile_data
|
|
28
|
+
from codeaois.agents.tester_agent import run_test
|
|
29
|
+
|
|
30
|
+
# Print Colors
|
|
31
|
+
C_BLUE = '\033[94m'
|
|
32
|
+
C_GREEN = '\033[92m'
|
|
33
|
+
C_YELLOW = '\033[93m'
|
|
34
|
+
C_PURPLE = '\033[95m'
|
|
35
|
+
C_CYAN = '\033[96m'
|
|
36
|
+
C_RESET = '\033[0m'
|
|
37
|
+
C_BOLD = '\033[1m'
|
|
38
|
+
|
|
39
|
+
# Globals
|
|
40
|
+
console = Console()
|
|
41
|
+
chat_history = load_history()
|
|
42
|
+
active_file = None # The OS remembers the file you are working on
|
|
43
|
+
|
|
44
|
+
# --- CONFIGURE AUTOCOMPLETE OPTIONS ---
|
|
45
|
+
AVAILABLE_COMMANDS = [
|
|
46
|
+
'/help', '/clear', '/clear_history', '/clear_user',
|
|
47
|
+
'/status', '/marketplace', '/install', '/exit', '/quit'
|
|
48
|
+
]
|
|
49
|
+
command_completer = WordCompleter(AVAILABLE_COMMANDS, ignore_case=True)
|
|
50
|
+
|
|
51
|
+
def print_logo():
|
|
52
|
+
logo = f"""{C_BLUE}{C_BOLD}
|
|
53
|
+
____ _ _ ___ _____ _____
|
|
54
|
+
/ ___|___ __| | ___ / \\ / _ \\_ _|/ ____|
|
|
55
|
+
| | / _ \\ / _` |/ _ \\/ _ \\| | | || | | (___
|
|
56
|
+
| |__| (_) | (_| | __/ ___ \\ |_| || |_ \\___ \\
|
|
57
|
+
\\____\\___/ \\__,_|\\___/_/ \\_\\___/_____|____/
|
|
58
|
+
{C_RESET}"""
|
|
59
|
+
print(logo)
|
|
60
|
+
print(f"{C_CYAN} โถ Advanced AI Developer OS v0.1.0{C_RESET}")
|
|
61
|
+
print(f"{C_CYAN} โถ Type /help to see available commands.{C_RESET}\n")
|
|
62
|
+
|
|
63
|
+
def show_help():
|
|
64
|
+
print(f"\n{C_PURPLE}=== CodeAOIS Command Center ==={C_RESET}")
|
|
65
|
+
print(f"{C_YELLOW}/marketplace{C_RESET} - View available specialized agents")
|
|
66
|
+
print(f"{C_YELLOW}/install <x>{C_RESET} - Download an agent (e.g., /install database)")
|
|
67
|
+
print(f"{C_YELLOW}/clear{C_RESET} - Clear the terminal screen")
|
|
68
|
+
print(f"{C_YELLOW}/clear_history{C_RESET} - Wipe your conversation memory")
|
|
69
|
+
print(f"{C_YELLOW}/clear_user{C_RESET} - Wipe your profile and restart setup")
|
|
70
|
+
print(f"{C_YELLOW}/status{C_RESET} - View current OS constraints and active models")
|
|
71
|
+
print(f"{C_YELLOW}/exit{C_RESET} - Close the CodeAOIS environment")
|
|
72
|
+
print(f"{C_PURPLE}==============================={C_RESET}\n")
|
|
73
|
+
|
|
74
|
+
def show_status():
|
|
75
|
+
print(f"\n{C_BLUE}[OS Status]{C_RESET}")
|
|
76
|
+
print(" ๐ข Core Engine: Online")
|
|
77
|
+
print(" ๐ข Model Router: Liquid/Arcee (Chat) | Step/Qwen (Code)")
|
|
78
|
+
print(" ๐ข Project Brain: Active")
|
|
79
|
+
print(" ๐ข Plugin Architecture: Dynamic Auto-Discovery")
|
|
80
|
+
print(" ๐ข UI Engine: Prompt Toolkit & Rich Markdown")
|
|
81
|
+
print(" ๐ข Security Dry-Run: Enabled\n")
|
|
82
|
+
|
|
83
|
+
def process_command(user_input: str):
|
|
84
|
+
global chat_history, active_file
|
|
85
|
+
clean_input = user_input.lower().strip()
|
|
86
|
+
|
|
87
|
+
if clean_input in ["/exit", "/quit", "exit", "quit"]:
|
|
88
|
+
print(f"\n{C_GREEN}๐ Terminating CodeAOIS session. Happy coding!{C_RESET}")
|
|
89
|
+
sys.exit(0)
|
|
90
|
+
|
|
91
|
+
if clean_input == "/help":
|
|
92
|
+
show_help()
|
|
93
|
+
return
|
|
94
|
+
|
|
95
|
+
if clean_input == "/clear":
|
|
96
|
+
os.system('clear' if os.name == 'posix' else 'cls')
|
|
97
|
+
print_logo()
|
|
98
|
+
return
|
|
99
|
+
|
|
100
|
+
if clean_input == "/clear_history":
|
|
101
|
+
chat_history.clear()
|
|
102
|
+
clear_history_data()
|
|
103
|
+
print(f"\n{C_GREEN}๐งน Conversation history wiped clean. I have amnesia!{C_RESET}\n")
|
|
104
|
+
return
|
|
105
|
+
|
|
106
|
+
if clean_input == "/clear_user":
|
|
107
|
+
clear_profile_data()
|
|
108
|
+
print(f"\n{C_GREEN}๐ค User profile deleted. Exiting so you can restart setup...{C_RESET}\n")
|
|
109
|
+
sys.exit(0)
|
|
110
|
+
|
|
111
|
+
if clean_input == "/status":
|
|
112
|
+
show_status()
|
|
113
|
+
return
|
|
114
|
+
|
|
115
|
+
if clean_input == "/marketplace":
|
|
116
|
+
installed = get_installed_agents()
|
|
117
|
+
|
|
118
|
+
# --- 1. THE EXPANDED AGENT REGISTRY ---
|
|
119
|
+
available_agents = {
|
|
120
|
+
"database": {
|
|
121
|
+
"desc": "SQL, NoSQL, ORM",
|
|
122
|
+
"summary": "Writes optimized queries, designs schemas, and handles database migrations."
|
|
123
|
+
},
|
|
124
|
+
"3d": {
|
|
125
|
+
"desc": "Three.js, WebGL, Unity",
|
|
126
|
+
"summary": "Generates complex 3D math, shaders, and game engine scripts."
|
|
127
|
+
},
|
|
128
|
+
"debugging": {
|
|
129
|
+
"desc": "Deep Error Analysis",
|
|
130
|
+
"summary": "Reads crash logs, finds root causes, and suggests exact line-by-line fixes."
|
|
131
|
+
},
|
|
132
|
+
"devops": {
|
|
133
|
+
"desc": "Docker, CI/CD, AWS",
|
|
134
|
+
"summary": "Writes Dockerfiles, GitHub Actions, and infrastructure automation."
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
# --- 2. BUILD THE STUNNING UI TABLE ---
|
|
139
|
+
print("\n")
|
|
140
|
+
table = Table(title="๐ CodeAOIS Agent Marketplace", border_style="purple", header_style="bold cyan")
|
|
141
|
+
table.add_column("Agent Name", style="bold white", no_wrap=True)
|
|
142
|
+
table.add_column("Status", justify="center")
|
|
143
|
+
table.add_column("Core Focus", style="magenta")
|
|
144
|
+
table.add_column("Agent Capabilities", style="dim")
|
|
145
|
+
|
|
146
|
+
for agent, info in available_agents.items():
|
|
147
|
+
if agent in installed:
|
|
148
|
+
status = "[bold green]โ Installed[/bold green]"
|
|
149
|
+
else:
|
|
150
|
+
status = "[bold yellow]โ Available[/bold yellow]"
|
|
151
|
+
|
|
152
|
+
table.add_row(agent.title(), status, info["desc"], info["summary"])
|
|
153
|
+
|
|
154
|
+
console.print(table)
|
|
155
|
+
print("\n")
|
|
156
|
+
|
|
157
|
+
# --- 3. THE INTERACTIVE AUTO-INSTALLER ---
|
|
158
|
+
choice = input(f"{C_BLUE}Enter an agent name to install (or press Enter to close): {C_RESET}").strip().lower()
|
|
159
|
+
|
|
160
|
+
if choice in available_agents:
|
|
161
|
+
if choice in installed:
|
|
162
|
+
print(f"{C_YELLOW}โ ๏ธ You already have the {choice.title()} Agent installed!{C_RESET}\n")
|
|
163
|
+
else:
|
|
164
|
+
print(f"{C_GREEN}โฌ๏ธ Downloading {choice.title()} Agent from registry...{C_RESET}")
|
|
165
|
+
install_agent(choice)
|
|
166
|
+
print(f"{C_GREEN}โ
{choice.title()} Agent successfully integrated into the OS!{C_RESET}\n")
|
|
167
|
+
elif choice:
|
|
168
|
+
print(f"{C_YELLOW}โ ๏ธ Agent '{choice}' not found in the marketplace.{C_RESET}\n")
|
|
169
|
+
|
|
170
|
+
return
|
|
171
|
+
|
|
172
|
+
if clean_input.startswith("/install"):
|
|
173
|
+
parts = clean_input.split()
|
|
174
|
+
if len(parts) > 1:
|
|
175
|
+
agent_target = parts[1].strip()
|
|
176
|
+
install_agent(agent_target)
|
|
177
|
+
else:
|
|
178
|
+
print(f"\n{C_YELLOW}โ ๏ธ Missing agent name! Please specify an agent (e.g., /install database){C_RESET}\n")
|
|
179
|
+
return
|
|
180
|
+
|
|
181
|
+
print(f"\n{C_CYAN}[System]{C_RESET} Analyzing intent...")
|
|
182
|
+
intent = analyze_intent(user_input)
|
|
183
|
+
|
|
184
|
+
if intent == "chat":
|
|
185
|
+
print(f"{C_BLUE}๐ฌ [Chat Mode]{C_RESET} Asking AI...")
|
|
186
|
+
|
|
187
|
+
profile = load_profile()
|
|
188
|
+
user_name = profile["name"] if profile else "Developer"
|
|
189
|
+
user_role = profile["role"] if profile else "Coding"
|
|
190
|
+
|
|
191
|
+
project_tree = scan_project_structure()
|
|
192
|
+
|
|
193
|
+
system_prompt = (
|
|
194
|
+
f"You are CodeAOIS, an advanced AI Developer OS running directly in the user's terminal. "
|
|
195
|
+
f"The user's name is {user_name} ({user_role}).\n"
|
|
196
|
+
f"CRITICAL: You have FULL access to the user's file system. Here is their current project structure:\n{project_tree}\n"
|
|
197
|
+
f"Currently focused file: {active_file if active_file else 'None'}\n"
|
|
198
|
+
f"If the user asks 'can you see my code' or asks about their files, say YES and reference the project structure. "
|
|
199
|
+
f"DO NOT EVER say you cannot view files."
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
response = call_openrouter(system_prompt, user_input, intent="chat", history=chat_history)
|
|
203
|
+
print(f"\n{C_BOLD}๐ค CodeAOIS:{C_RESET} {response}\n")
|
|
204
|
+
|
|
205
|
+
chat_history.append({"role": "user", "content": user_input})
|
|
206
|
+
chat_history.append({"role": "assistant", "content": response})
|
|
207
|
+
if len(chat_history) > 20: chat_history = chat_history[-20:]
|
|
208
|
+
save_history(chat_history)
|
|
209
|
+
|
|
210
|
+
elif intent in ["code", "data_science"] or intent.endswith("_agent"):
|
|
211
|
+
|
|
212
|
+
if intent == "data_science":
|
|
213
|
+
print(f"{C_PURPLE}๐ [Data Science Mode]{C_RESET} Engaging specialized agent...")
|
|
214
|
+
elif intent == "code":
|
|
215
|
+
print(f"{C_GREEN}โ๏ธ [Code Mode]{C_RESET} Engaging Coder agent...")
|
|
216
|
+
else:
|
|
217
|
+
plugin_name = intent.replace('_agent', '').title()
|
|
218
|
+
print(f"{C_PURPLE}๐ [Plugin Mode]{C_RESET} Engaging specialized {plugin_name} Agent...")
|
|
219
|
+
|
|
220
|
+
target_file, file_context = extract_file_context(user_input)
|
|
221
|
+
|
|
222
|
+
# ACTIVE FILE MEMORY
|
|
223
|
+
if not target_file and active_file:
|
|
224
|
+
print(f" ๐ Auto-locking to previous file: {active_file}")
|
|
225
|
+
target_file = active_file
|
|
226
|
+
if os.path.exists(active_file):
|
|
227
|
+
with open(active_file, "r", encoding="utf-8") as f:
|
|
228
|
+
file_context = f.read()
|
|
229
|
+
|
|
230
|
+
if target_file:
|
|
231
|
+
active_file = target_file
|
|
232
|
+
print(f" ๐ Target file locked: {target_file}")
|
|
233
|
+
|
|
234
|
+
print(f" ๐ง Scanning project context...")
|
|
235
|
+
project_tree = scan_project_structure()
|
|
236
|
+
|
|
237
|
+
brain_context = f"\n--- Project Structure Overview ---\n{project_tree}\n----------------------------------\n"
|
|
238
|
+
full_context = brain_context + file_context if file_context else brain_context
|
|
239
|
+
|
|
240
|
+
print(f" {C_YELLOW}โก Generating code...{C_RESET}")
|
|
241
|
+
|
|
242
|
+
# --- GENERATE THE CODE_RESULT VARIABLE ---
|
|
243
|
+
if intent == "data_science":
|
|
244
|
+
code_result = generate_ds_code(user_input, full_context)
|
|
245
|
+
elif intent == "code":
|
|
246
|
+
code_result = generate_code(user_input, full_context)
|
|
247
|
+
else:
|
|
248
|
+
try:
|
|
249
|
+
module = importlib.import_module(f"codeaois.agents.{intent}")
|
|
250
|
+
func_name = f"generate_{intent.replace('_agent', '')}_code"
|
|
251
|
+
agent_func = getattr(module, func_name)
|
|
252
|
+
code_result = agent_func(user_input, full_context)
|
|
253
|
+
except Exception as e:
|
|
254
|
+
print(f"\n{C_YELLOW}โ ๏ธ Error executing plugin {intent}: {e}{C_RESET}")
|
|
255
|
+
return
|
|
256
|
+
|
|
257
|
+
# --- EXTRACT SAVE PATH ---
|
|
258
|
+
if target_file:
|
|
259
|
+
save_path = target_file
|
|
260
|
+
else:
|
|
261
|
+
print("\n" + "-"*50)
|
|
262
|
+
custom_name = input(f"{C_BLUE}๐ Enter filename with extension (e.g., app.py): {C_RESET}").strip()
|
|
263
|
+
save_path = custom_name if custom_name else "untitled_generation.txt"
|
|
264
|
+
print("-"*50)
|
|
265
|
+
|
|
266
|
+
# --- SAVE AND SHOW SUMMARY ---
|
|
267
|
+
success, ai_summary = extract_and_save_code(code_result, default_filename=save_path)
|
|
268
|
+
if success:
|
|
269
|
+
auto_commit(save_path, message=f"CodeAOIS auto-update: {save_path} via {intent}")
|
|
270
|
+
print("\n")
|
|
271
|
+
md = Markdown(ai_summary)
|
|
272
|
+
console.print(Panel(md, title="[bold cyan]Agent Summary[/bold cyan]", border_style="cyan", expand=False))
|
|
273
|
+
print("\n")
|
|
274
|
+
|
|
275
|
+
# --- NEW: BRIDGE THE BRAINS ---
|
|
276
|
+
# Inject the coding action into the shared chat memory!
|
|
277
|
+
chat_history.append({"role": "user", "content": user_input})
|
|
278
|
+
chat_history.append({
|
|
279
|
+
"role": "assistant",
|
|
280
|
+
"content": f"[System Log: I successfully generated code and saved it to '{save_path}'. Here is my summary of what I did: {ai_summary}]"
|
|
281
|
+
})
|
|
282
|
+
if len(chat_history) > 20: chat_history = chat_history[-20:]
|
|
283
|
+
save_history(chat_history)
|
|
284
|
+
# --- NEW: THE MULTI-AGENT TESTER LOOP ---
|
|
285
|
+
if save_path.endswith('.py'):
|
|
286
|
+
confirm_test = input(f"{C_PURPLE}๐งช [Tester Agent] Shall I execute '{save_path}' to check for errors? [Y/n]: {C_RESET}").strip().lower()
|
|
287
|
+
|
|
288
|
+
if confirm_test in ['y', '']:
|
|
289
|
+
print(f" {C_PURPLE}โ๏ธ Running tests...{C_RESET}")
|
|
290
|
+
test_success, test_output = run_test(save_path)
|
|
291
|
+
|
|
292
|
+
if test_success:
|
|
293
|
+
print(f"{C_GREEN}โ
Test Passed! Terminal Output:\n{C_RESET}{test_output}\n")
|
|
294
|
+
else:
|
|
295
|
+
print(f"{C_YELLOW}โ Test Failed! Crash Log:\n{C_RESET}{test_output}\n")
|
|
296
|
+
|
|
297
|
+
# The Loop-Back!
|
|
298
|
+
fix_confirm = input(f"{C_PURPLE}๐ Pass crash log back to Coder Agent to fix? [Y/n]: {C_RESET}").strip().lower()
|
|
299
|
+
if fix_confirm in ['y', '']:
|
|
300
|
+
print(f"{C_GREEN}โ๏ธ Re-Engaging Coder agent for bug fix...{C_RESET}")
|
|
301
|
+
|
|
302
|
+
# Automatically generate a new prompt with the error log
|
|
303
|
+
fix_prompt = f"I ran {save_path} and got this error:\n{test_output}\nPlease fix the code."
|
|
304
|
+
|
|
305
|
+
# Recursively call the command processor to handle the fix!
|
|
306
|
+
process_command(fix_prompt)
|
|
307
|
+
else:
|
|
308
|
+
print(f"{C_YELLOW}โ Unknown intent. Please try rephrasing.{C_RESET}")
|
|
309
|
+
|
|
310
|
+
def main():
|
|
311
|
+
parser = argparse.ArgumentParser(
|
|
312
|
+
description="CodeAOIS: Advanced AI Developer OS",
|
|
313
|
+
usage="codeaois [prompt] or codeaois [options]"
|
|
314
|
+
)
|
|
315
|
+
parser.add_argument("prompt", nargs="*", help="Chat or command for CodeAOIS")
|
|
316
|
+
parser.add_argument("-v", "--version", action="version", version="CodeAOIS Core Engine v0.1.0")
|
|
317
|
+
args = parser.parse_args()
|
|
318
|
+
|
|
319
|
+
profile = load_profile()
|
|
320
|
+
if not profile:
|
|
321
|
+
profile = create_profile()
|
|
322
|
+
|
|
323
|
+
if args.prompt:
|
|
324
|
+
user_input = " ".join(args.prompt)
|
|
325
|
+
process_command(user_input)
|
|
326
|
+
sys.exit(0)
|
|
327
|
+
|
|
328
|
+
os.system('clear' if os.name == 'posix' else 'cls')
|
|
329
|
+
print_logo()
|
|
330
|
+
|
|
331
|
+
if profile:
|
|
332
|
+
print(f"{C_CYAN} Welcome back, {profile.get('name', 'Developer')}!{C_RESET}\n")
|
|
333
|
+
|
|
334
|
+
session = PromptSession(
|
|
335
|
+
completer=command_completer,
|
|
336
|
+
auto_suggest=AutoSuggestFromHistory(),
|
|
337
|
+
complete_while_typing=True
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
while True:
|
|
341
|
+
try:
|
|
342
|
+
user_input = session.prompt(HTML('<b><ansigreen>CodeAOIS></ansigreen></b> ')).strip()
|
|
343
|
+
if not user_input:
|
|
344
|
+
continue
|
|
345
|
+
process_command(user_input)
|
|
346
|
+
except KeyboardInterrupt:
|
|
347
|
+
print(f"\n{C_GREEN}๐ Terminating CodeAOIS session. Happy coding!{C_RESET}")
|
|
348
|
+
sys.exit(0)
|
|
349
|
+
|
|
350
|
+
if __name__ == "__main__":
|
|
351
|
+
main()
|