🍌🐒 commited on
Commit
beb52ea
·
1 Parent(s): dab7e4c

Add simplified source files for Hugging Face Space

Browse files
Files changed (6) hide show
  1. src/__init__.py +5 -0
  2. src/agents.py +58 -0
  3. src/config.py +44 -0
  4. src/logger.py +40 -0
  5. src/project.py +34 -0
  6. src/state.py +14 -0
src/__init__.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ """
2
+ Devika AI Assistant - A powerful AI coding assistant
3
+ """
4
+
5
+ __version__ = "0.1.0"
src/agents.py ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from typing import Optional
3
+ import openai
4
+ import anthropic
5
+ from duckduckgo_search import DDGS
6
+
7
+ class Agent:
8
+ def __init__(self, base_model: str = "gpt-3.5-turbo", search_engine: str = "duckduckgo"):
9
+ self.base_model = base_model
10
+ self.search_engine = search_engine
11
+
12
+ # Initialize API clients
13
+ if "gpt" in base_model:
14
+ openai.api_key = os.getenv("OPENAI_API_KEY")
15
+ elif "claude" in base_model:
16
+ self.claude = anthropic.Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
17
+
18
+ def execute(self, message: str, project_name: str) -> Optional[str]:
19
+ try:
20
+ # Process the message based on the selected model
21
+ if "gpt" in self.base_model:
22
+ response = self._process_with_gpt(message)
23
+ elif "claude" in self.base_model:
24
+ response = self._process_with_claude(message)
25
+ else:
26
+ response = "Unsupported model selected"
27
+
28
+ return response
29
+ except Exception as e:
30
+ return f"Error processing message: {str(e)}"
31
+
32
+ def subsequent_execute(self, message: str, project_name: str) -> Optional[str]:
33
+ return self.execute(message, project_name)
34
+
35
+ def _process_with_gpt(self, message: str) -> str:
36
+ response = openai.chat.completions.create(
37
+ model=self.base_model,
38
+ messages=[{"role": "user", "content": message}]
39
+ )
40
+ return response.choices[0].message.content
41
+
42
+ def _process_with_claude(self, message: str) -> str:
43
+ message = anthropic.Message(
44
+ role="user",
45
+ content=message
46
+ )
47
+ response = self.claude.messages.create(
48
+ model="claude-3-opus-20240229",
49
+ messages=[message]
50
+ )
51
+ return response.content[0].text
52
+
53
+ def _search_web(self, query: str, num_results: int = 5) -> list:
54
+ if self.search_engine == "duckduckgo":
55
+ with DDGS() as ddgs:
56
+ return list(ddgs.text(query, max_results=num_results))
57
+ # Add support for other search engines as needed
58
+ return []
src/config.py ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ from pathlib import Path
4
+
5
+ class Config:
6
+ _instance = None
7
+
8
+ def __new__(cls):
9
+ if cls._instance is None:
10
+ cls._instance = super().__new__(cls)
11
+ cls._instance._load_config()
12
+ return cls._instance
13
+
14
+ def _load_config(self):
15
+ self.config = {
16
+ "API_KEYS": {
17
+ "OPENAI": os.getenv("OPENAI_API_KEY", ""),
18
+ "ANTHROPIC": os.getenv("ANTHROPIC_API_KEY", ""),
19
+ "BING": os.getenv("BING_API_KEY", ""),
20
+ "GOOGLE_SEARCH": os.getenv("GOOGLE_API_KEY", ""),
21
+ "GOOGLE_SEARCH_ENGINE_ID": os.getenv("GOOGLE_SEARCH_ENGINE_ID", ""),
22
+ },
23
+ "API_ENDPOINTS": {
24
+ "BING": "https://api.bing.microsoft.com/v7.0/search",
25
+ "GOOGLE": "https://www.googleapis.com/customsearch/v1",
26
+ }
27
+ }
28
+
29
+ # Create necessary directories
30
+ base_dir = Path("/code")
31
+ for dir_name in ["db", "logs", "projects", "screenshots", "pdfs"]:
32
+ (base_dir / dir_name).mkdir(exist_ok=True)
33
+
34
+ def get_config(self):
35
+ return self.config
36
+
37
+ def get_bing_api_key(self):
38
+ return self.config["API_KEYS"]["BING"]
39
+
40
+ def get_google_search_api_key(self):
41
+ return self.config["API_KEYS"]["GOOGLE_SEARCH"]
42
+
43
+ def get_google_search_engine_id(self):
44
+ return self.config["API_KEYS"]["GOOGLE_SEARCH_ENGINE_ID"]
src/logger.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ from pathlib import Path
3
+
4
+ class Logger:
5
+ def __init__(self, filename="devika_agent.log"):
6
+ # Set up logging
7
+ self.log_dir = Path("/code/logs")
8
+ self.log_dir.mkdir(exist_ok=True)
9
+ self.log_file = self.log_dir / filename
10
+
11
+ # Configure logging
12
+ logging.basicConfig(
13
+ level=logging.INFO,
14
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
15
+ handlers=[
16
+ logging.FileHandler(self.log_file),
17
+ logging.StreamHandler()
18
+ ]
19
+ )
20
+ self.logger = logging.getLogger("devika")
21
+
22
+ def info(self, message: str):
23
+ self.logger.info(message)
24
+
25
+ def error(self, message: str):
26
+ self.logger.error(message)
27
+
28
+ def warning(self, message: str):
29
+ self.logger.warning(message)
30
+
31
+ def debug(self, message: str):
32
+ self.logger.debug(message)
33
+
34
+ def route_logger(logger):
35
+ def decorator(f):
36
+ def wrapper(*args, **kwargs):
37
+ logger.info(f"Route called: {f.__name__}")
38
+ return f(*args, **kwargs)
39
+ return wrapper
40
+ return decorator
src/project.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from datetime import datetime
3
+ from pathlib import Path
4
+
5
+ class ProjectManager:
6
+ def __init__(self):
7
+ self.projects_dir = Path("/code/projects")
8
+ self.projects_dir.mkdir(exist_ok=True)
9
+ self.messages = {}
10
+
11
+ def new_message(self):
12
+ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
13
+ return {
14
+ "from_devika": True,
15
+ "message": None,
16
+ "timestamp": timestamp
17
+ }
18
+
19
+ def get_messages(self, project_name: str):
20
+ if project_name not in self.messages:
21
+ self.messages[project_name] = []
22
+ return self.messages[project_name]
23
+
24
+ def add_message(self, project_name: str, message: str, from_devika: bool = True):
25
+ if project_name not in self.messages:
26
+ self.messages[project_name] = []
27
+
28
+ msg = {
29
+ "from_devika": from_devika,
30
+ "message": message,
31
+ "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
32
+ }
33
+ self.messages[project_name].append(msg)
34
+ return msg
src/state.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class AgentState:
2
+ def __init__(self):
3
+ self.states = {}
4
+
5
+ def get_latest_state(self, project_name: str):
6
+ return self.states.get(project_name, None)
7
+
8
+ def is_agent_completed(self, project_name: str):
9
+ state = self.get_latest_state(project_name)
10
+ return state.get("completed", True) if state else True
11
+
12
+ def is_agent_active(self, project_name: str):
13
+ state = self.get_latest_state(project_name)
14
+ return state.get("agent_is_active", False) if state else False