jarvis-ai-assistant 0.1.97__py3-none-any.whl → 0.1.99__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.

Potentially problematic release.


This version of jarvis-ai-assistant might be problematic. Click here for more details.

Files changed (41) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/agent.py +199 -157
  3. jarvis/jarvis_code_agent/__init__.py +0 -0
  4. jarvis/jarvis_code_agent/main.py +203 -0
  5. jarvis/jarvis_codebase/main.py +412 -284
  6. jarvis/jarvis_coder/file_select.py +209 -0
  7. jarvis/jarvis_coder/git_utils.py +81 -19
  8. jarvis/jarvis_coder/main.py +68 -446
  9. jarvis/jarvis_coder/patch_handler.py +117 -47
  10. jarvis/jarvis_coder/plan_generator.py +69 -27
  11. jarvis/jarvis_platform/main.py +38 -38
  12. jarvis/jarvis_rag/main.py +189 -189
  13. jarvis/jarvis_smart_shell/main.py +22 -24
  14. jarvis/models/base.py +6 -1
  15. jarvis/models/ollama.py +2 -2
  16. jarvis/models/registry.py +3 -6
  17. jarvis/tools/ask_user.py +6 -6
  18. jarvis/tools/codebase_qa.py +5 -7
  19. jarvis/tools/create_code_sub_agent.py +55 -0
  20. jarvis/tools/{sub_agent.py → create_sub_agent.py} +4 -1
  21. jarvis/tools/execute_code_modification.py +72 -0
  22. jarvis/tools/{file_ops.py → file_operation.py} +13 -14
  23. jarvis/tools/find_related_files.py +86 -0
  24. jarvis/tools/methodology.py +25 -25
  25. jarvis/tools/rag.py +32 -32
  26. jarvis/tools/registry.py +72 -36
  27. jarvis/tools/search.py +1 -1
  28. jarvis/tools/select_code_files.py +64 -0
  29. jarvis/utils.py +153 -49
  30. {jarvis_ai_assistant-0.1.97.dist-info → jarvis_ai_assistant-0.1.99.dist-info}/METADATA +1 -1
  31. jarvis_ai_assistant-0.1.99.dist-info/RECORD +52 -0
  32. {jarvis_ai_assistant-0.1.97.dist-info → jarvis_ai_assistant-0.1.99.dist-info}/entry_points.txt +2 -1
  33. jarvis/main.py +0 -155
  34. jarvis/tools/coder.py +0 -69
  35. jarvis_ai_assistant-0.1.97.dist-info/RECORD +0 -47
  36. /jarvis/tools/{shell.py → execute_shell.py} +0 -0
  37. /jarvis/tools/{generator.py → generate_tool.py} +0 -0
  38. /jarvis/tools/{webpage.py → read_webpage.py} +0 -0
  39. {jarvis_ai_assistant-0.1.97.dist-info → jarvis_ai_assistant-0.1.99.dist-info}/LICENSE +0 -0
  40. {jarvis_ai_assistant-0.1.97.dist-info → jarvis_ai_assistant-0.1.99.dist-info}/WHEEL +0 -0
  41. {jarvis_ai_assistant-0.1.97.dist-info → jarvis_ai_assistant-0.1.99.dist-info}/top_level.txt +0 -0
@@ -4,48 +4,46 @@ import os
4
4
  import sys
5
5
  import readline
6
6
  from typing import Optional
7
- from yaspin import yaspin
8
- from yaspin.spinners import Spinners
7
+ from yaspin import yaspin # type: ignore
8
+ from yaspin.spinners import Spinners # type: ignore
9
9
 
10
10
  from jarvis.models.registry import PlatformRegistry
11
- from jarvis.utils import PrettyOutput, OutputType, load_env_from_file
11
+ from jarvis.utils import PrettyOutput, OutputType, get_single_line_input, load_env_from_file
12
12
 
13
13
  def execute_command(command: str) -> None:
14
- """显示命令并允许用户编辑,回车执行,Ctrl+C取消"""
14
+ """Show command and allow user to edit, then execute, Ctrl+C to cancel"""
15
15
  try:
16
- print("\n生成的命令 (可以编辑,回车执行,Ctrl+C取消):")
17
- # 预填充输入行
16
+ # Pre-fill input line
18
17
  readline.set_startup_hook(lambda: readline.insert_text(command))
19
18
  try:
20
- edited_command = input("> ")
21
- if edited_command.strip(): # 确保命令不为空
19
+ edited_command = get_single_line_input("Generated command (can be edited, press Enter to execute, Ctrl+C to cancel)")
20
+ if edited_command.strip(): # Ensure command is not empty
22
21
  os.system(edited_command)
23
22
  except KeyboardInterrupt:
24
- print("\n已取消执行")
23
+ PrettyOutput.print("Execution cancelled", OutputType.INFO)
25
24
  finally:
26
- readline.set_startup_hook() # 清除预填充
25
+ readline.set_startup_hook() # Clear pre-filled
27
26
  except Exception as e:
28
- PrettyOutput.print(f"执行命令时发生错误: {str(e)}", OutputType.ERROR)
27
+ PrettyOutput.print(f"Failed to execute command: {str(e)}", OutputType.ERROR)
29
28
 
30
29
  def process_request(request: str) -> Optional[str]:
31
- """处理用户请求并返回对应的shell命令
30
+ """Process user request and return corresponding shell command
32
31
 
33
32
  Args:
34
- request: 用户的自然语言请求
33
+ request: User's natural language request
35
34
 
36
35
  Returns:
37
- Optional[str]: 对应的shell命令,如果处理失败则返回None
36
+ Optional[str]: Corresponding shell command, return None if processing fails
38
37
  """
39
38
  try:
40
- # 获取语言模型实例
41
- PlatformRegistry.suppress_output = True
39
+ # Get language model instance
42
40
  model = PlatformRegistry.get_global_platform_registry().get_normal_platform()
43
41
  model.set_suppress_output(True)
44
42
 
45
43
  shell = os.environ.get("SHELL") or "bash"
46
44
  current_path = os.getcwd()
47
45
 
48
- # 设置系统提示
46
+ # Set system prompt
49
47
  system_message = f"""You are a shell command generation assistant.
50
48
 
51
49
  Your only task is to convert user's natural language requirements into corresponding shell commands.
@@ -85,26 +83,26 @@ Remember: Only return the command itself, without any additional content.
85
83
  return None
86
84
 
87
85
  except Exception as e:
88
- PrettyOutput.print(f"处理请求时发生错误: {str(e)}", OutputType.ERROR)
86
+ PrettyOutput.print(f"Failed to process request: {str(e)}", OutputType.ERROR)
89
87
  return None
90
88
 
91
89
  def main():
92
90
  # 创建参数解析器
93
91
  load_env_from_file()
94
92
  parser = argparse.ArgumentParser(
95
- description="将自然语言需求转换为shell命令",
93
+ description="Convert natural language requirements to shell commands",
96
94
  formatter_class=argparse.RawDescriptionHelpFormatter,
97
95
  epilog="""
98
- 示例:
99
- %(prog)s "查找当前目录下所有的Python文件"
100
- %(prog)s "压缩所有jpg图片"
101
- %(prog)s "查找最近一周修改过的文档"
96
+ Example:
97
+ %(prog)s "Find all Python files in the current directory"
98
+ %(prog)s "Compress all jpg images"
99
+ %(prog)s "Find documents modified in the last week"
102
100
  """)
103
101
 
104
102
  # 添加参数
105
103
  parser.add_argument(
106
104
  "request",
107
- help="用自然语言描述你需要执行的操作"
105
+ help="Describe the operation you want to perform in natural language"
108
106
  )
109
107
 
110
108
  # 解析参数
jarvis/models/base.py CHANGED
@@ -1,4 +1,5 @@
1
1
  from abc import ABC, abstractmethod
2
+ import re
2
3
  from typing import Dict, List, Tuple
3
4
 
4
5
  from jarvis.utils import OutputType, PrettyOutput, while_success, while_true
@@ -26,7 +27,11 @@ class BasePlatform(ABC):
26
27
  raise NotImplementedError("chat is not implemented")
27
28
 
28
29
  def chat_until_success(self, message: str) -> str:
29
- return while_true(lambda: while_success(lambda: self.chat(message), 5), 5)
30
+ def _chat():
31
+ response = self.chat(message)
32
+ response = re.sub(r'<think>(.*?)</think>', '', response, flags=re.DOTALL)
33
+ return response
34
+ return while_true(lambda: while_success(lambda: _chat(), 5), 5)
30
35
 
31
36
  @abstractmethod
32
37
  def upload_files(self, file_list: List[str]) -> List[Dict]:
jarvis/models/ollama.py CHANGED
@@ -1,7 +1,7 @@
1
1
  import requests
2
2
  from typing import List, Dict, Tuple
3
3
  from jarvis.models.base import BasePlatform
4
- from jarvis.utils import OutputType, PrettyOutput
4
+ from jarvis.utils import OutputType, PrettyOutput, get_single_line_input
5
5
  import os
6
6
  import json
7
7
 
@@ -136,7 +136,7 @@ if __name__ == "__main__":
136
136
  ollama = OllamaPlatform()
137
137
  while True:
138
138
  try:
139
- message = input("\nInput question (Ctrl+C to exit): ")
139
+ message = get_single_line_input("\nInput question (Ctrl+C to exit)")
140
140
  ollama.chat_until_success(message)
141
141
  except KeyboardInterrupt:
142
142
  print("\nGoodbye!")
jarvis/models/registry.py CHANGED
@@ -3,8 +3,8 @@ import inspect
3
3
  import os
4
4
  import sys
5
5
  from typing import Dict, Type, Optional, List
6
- from .base import BasePlatform
7
- from ..utils import PrettyOutput, OutputType
6
+ from jarvis.models.base import BasePlatform
7
+ from jarvis.utils import PrettyOutput, OutputType
8
8
 
9
9
  REQUIRED_METHODS = [
10
10
  ('chat', ['message']), # 方法名和参数列表
@@ -23,7 +23,6 @@ class PlatformRegistry:
23
23
 
24
24
  global_platform_name = "kimi"
25
25
  global_platform_registry = None
26
- suppress_output = False
27
26
 
28
27
  @staticmethod
29
28
  def get_platform_dir() -> str:
@@ -117,7 +116,7 @@ class PlatformRegistry:
117
116
  module = importlib.import_module(module_name)
118
117
 
119
118
  # 遍历模块中的所有类
120
- for name, obj in inspect.getmembers(module):
119
+ for _, obj in inspect.getmembers(module):
121
120
  # 检查是否是BasePlatform的子类,但不是BasePlatform本身
122
121
  if (inspect.isclass(obj) and
123
122
  issubclass(obj, BasePlatform) and
@@ -126,8 +125,6 @@ class PlatformRegistry:
126
125
  # 检查平台实现
127
126
  if not PlatformRegistry.check_platform_implementation(obj):
128
127
  continue
129
- if not PlatformRegistry.suppress_output:
130
- PrettyOutput.print(f"Load platform from {os.path.join(directory, filename)}: {obj.platform_name}", OutputType.SUCCESS) # type: ignore
131
128
  platforms[obj.platform_name] = obj # type: ignore
132
129
  break
133
130
  except Exception as e:
jarvis/tools/ask_user.py CHANGED
@@ -18,22 +18,22 @@ class AskUserTool:
18
18
 
19
19
 
20
20
  def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
21
- """执行询问用户操作
21
+ """Execute the operation of asking the user
22
22
 
23
23
  Args:
24
- args: 包含问题的字典
24
+ args: A dictionary containing the question
25
25
 
26
26
  Returns:
27
- Dict: 包含用户响应的字典
27
+ Dict: A dictionary containing the user's response
28
28
  """
29
29
  try:
30
30
  question = args["question"]
31
31
 
32
- # 显示问题
33
- PrettyOutput.print("\n问题:", OutputType.SYSTEM)
32
+ # Display the question
33
+ PrettyOutput.print("\nQuestion:", OutputType.SYSTEM)
34
34
  PrettyOutput.print(question, OutputType.SYSTEM)
35
35
 
36
- # 获取用户输入
36
+ # Get user input
37
37
  user_response = get_multiline_input("Please enter your answer (input empty line to end)")
38
38
 
39
39
  if user_response == "__interrupt__":
@@ -4,7 +4,7 @@ from jarvis.jarvis_codebase.main import CodeBase
4
4
  from jarvis.utils import find_git_root, PrettyOutput, OutputType
5
5
 
6
6
  class CodebaseQATool:
7
- """代码库问答工具,用于回答关于代码库的问题"""
7
+ """Codebase QA Tool"""
8
8
 
9
9
  name = "codebase_qa"
10
10
  description = "Answer questions about the codebase, can query and understand code functionality, structure, and implementation details"
@@ -29,7 +29,7 @@ class CodebaseQATool:
29
29
  }
30
30
 
31
31
  def execute(self, params: Dict[str, Any]) -> Dict[str, Any]:
32
- """执行代码问答"""
32
+ """Execute codebase QA"""
33
33
  try:
34
34
  dir = params.get("dir")
35
35
  question = params["question"]
@@ -42,7 +42,7 @@ class CodebaseQATool:
42
42
  return {
43
43
  "success": False,
44
44
  "stdout": "",
45
- "stderr": "错误:当前目录不在Git仓库中",
45
+ "stderr": "Error: Current directory is not in a Git repository",
46
46
  "error": "NotInGitRepository"
47
47
  }
48
48
 
@@ -62,13 +62,11 @@ class CodebaseQATool:
62
62
  }
63
63
 
64
64
  except Exception as e:
65
- PrettyOutput.print(f"代码问答出错: {str(e)}", output_type=OutputType.ERROR)
65
+ PrettyOutput.print(f"Codebase QA error: {str(e)}", output_type=OutputType.ERROR)
66
66
  return {
67
67
  "success": False,
68
68
  "stdout": "",
69
- "stderr": f"执行代码问答时发生错误: {str(e)}",
69
+ "stderr": f"Error executing codebase QA: {str(e)}",
70
70
  "error": str(type(e).__name__)
71
71
  }
72
72
 
73
- def register():
74
- return CodebaseQATool()
@@ -0,0 +1,55 @@
1
+ from typing import Dict, Any
2
+
3
+ from jarvis.agent import Agent
4
+ from jarvis.utils import OutputType, PrettyOutput
5
+ from jarvis.jarvis_code_agent.main import system_prompt
6
+
7
+
8
+ class CodeSubAgentTool:
9
+ name = "create_code_sub_agent"
10
+ description = "Create a sub-agent to handle specific code development subtasks"
11
+ parameters = {
12
+ "type": "object",
13
+ "properties": {
14
+ "name": {
15
+ "type": "string",
16
+ "description": "The name of the sub-agent"
17
+ },
18
+ "subtask": {
19
+ "type": "string",
20
+ "description": "The specific code development subtask to complete"
21
+ },
22
+ },
23
+ "required": ["subtask", "name"]
24
+ }
25
+
26
+ def execute(self, args: Dict) -> Dict[str, Any]:
27
+ """Execute code development subtask"""
28
+ try:
29
+ subtask = args["subtask"]
30
+ name = args["name"]
31
+
32
+ PrettyOutput.print(f"Creating code sub-agent {name} for subtask: {subtask}", OutputType.INFO)
33
+
34
+ # Create sub-agent
35
+ sub_agent = Agent(
36
+ system_prompt=system_prompt,
37
+ name=name,
38
+ is_sub_agent=True
39
+ )
40
+
41
+ # Execute subtask
42
+ result = sub_agent.run(subtask)
43
+
44
+ return {
45
+ "success": True,
46
+ "stdout": f"Code Development Subtask Results:\n\n{result}",
47
+ "stderr": ""
48
+ }
49
+
50
+ except Exception as e:
51
+ PrettyOutput.print(str(e), OutputType.ERROR)
52
+ return {
53
+ "success": False,
54
+ "error": f"Failed to execute code development subtask: {str(e)}"
55
+ }
@@ -1,7 +1,7 @@
1
1
  from typing import Dict, Any
2
2
 
3
3
 
4
- from jarvis.agent import Agent
4
+ from jarvis.agent import Agent, origin_agent_system_prompt
5
5
  from jarvis.utils import OutputType, PrettyOutput
6
6
 
7
7
 
@@ -58,8 +58,11 @@ class SubAgentTool:
58
58
  if goal:
59
59
  task_description += f"\n\nCompletion goal:\n{goal}"
60
60
 
61
+
62
+
61
63
  # Create sub-agent
62
64
  sub_agent = Agent(
65
+ system_prompt=origin_agent_system_prompt,
63
66
  name=agent_name,
64
67
  is_sub_agent=True
65
68
  )
@@ -0,0 +1,72 @@
1
+ from typing import Dict, Any
2
+
3
+ from jarvis.agent import Agent
4
+ from jarvis.utils import OutputType, PrettyOutput
5
+ from jarvis.jarvis_coder.patch_handler import PatchHandler
6
+
7
+
8
+ class CodeModifyTool:
9
+ name = "execute_code_modification"
10
+ description = "Execute code modifications according to the provided plan"
11
+ parameters = {
12
+ "type": "object",
13
+ "properties": {
14
+ "task": {
15
+ "type": "string",
16
+ "description": "The code modification task description"
17
+ },
18
+ "structured_plan": {
19
+ "type": "object",
20
+ "description": "Dictionary mapping file paths to their modification plans. Example: {'path/to/file.py': 'Add function foo() to handle...'}",
21
+ "additionalProperties": {
22
+ "type": "string",
23
+ "description": "Modification plan for a specific file"
24
+ },
25
+ "examples": [{
26
+ "src/file1.py": "Add error handling to process_data()",
27
+ "src/file2.py": "Update API endpoint URL in get_data()"
28
+ }]
29
+ }
30
+ },
31
+ "required": ["task", "raw_plan", "structured_plan"]
32
+ }
33
+
34
+ def execute(self, args: Dict) -> Dict[str, Any]:
35
+ """Execute code modifications using PatchHandler"""
36
+ try:
37
+ task = args["task"]
38
+ structured_plan = args["structured_plan"]
39
+
40
+ PrettyOutput.print("Executing code modifications...", OutputType.INFO)
41
+
42
+ # Create patch handler instance
43
+ patch_handler = PatchHandler()
44
+
45
+ # Apply patches and handle the process
46
+ success = patch_handler.handle_patch_application(
47
+ feature=task,
48
+ structed_plan=structured_plan
49
+ )
50
+
51
+ if not success:
52
+ return {
53
+ "success": False,
54
+ "error": "Code modification was cancelled or failed",
55
+ "stdout": "Changes have been rolled back",
56
+ "stderr": ""
57
+ }
58
+
59
+ return {
60
+ "success": True,
61
+ "stdout": "Code modifications have been successfully applied and committed",
62
+ "stderr": ""
63
+ }
64
+
65
+ except Exception as e:
66
+ PrettyOutput.print(str(e), OutputType.ERROR)
67
+ return {
68
+ "success": False,
69
+ "error": f"Failed to execute code modifications: {str(e)}",
70
+ "stdout": "",
71
+ "stderr": str(e)
72
+ }
@@ -1,6 +1,5 @@
1
- from typing import Dict, Any, Protocol
1
+ from typing import Dict, Any
2
2
  import os
3
- from enum import Enum
4
3
 
5
4
  from jarvis.utils import OutputType, PrettyOutput
6
5
 
@@ -36,15 +35,15 @@ class FileOperationTool:
36
35
 
37
36
 
38
37
  def execute(self, args: Dict) -> Dict[str, Any]:
39
- """执行文件操作"""
38
+ """Execute file operations"""
40
39
  try:
41
40
  operation = args["operation"]
42
41
  filepath = args["filepath"]
43
42
  encoding = args.get("encoding", "utf-8")
44
43
 
45
- # 记录操作和完整路径
44
+ # Record the operation and the full path
46
45
  abs_path = os.path.abspath(filepath)
47
- PrettyOutput.print(f"文件操作: {operation} - {abs_path}", OutputType.INFO)
46
+ PrettyOutput.print(f"File operation: {operation} - {abs_path}", OutputType.INFO)
48
47
 
49
48
  if operation == "exists":
50
49
  exists = os.path.exists(filepath)
@@ -61,15 +60,15 @@ class FileOperationTool:
61
60
  "error": f"文件不存在: {filepath}"
62
61
  }
63
62
 
64
- # 检查文件大小
63
+ # Check file size
65
64
  if os.path.getsize(filepath) > 10 * 1024 * 1024: # 10MB
66
65
  return {
67
66
  "success": False,
68
- "error": "文件过大 (>10MB)"
67
+ "error": "File too large (>10MB)"
69
68
  }
70
69
 
71
- with open(filepath, 'r', encoding=encoding) as f:
72
- content = f.read()
70
+ content = open(filepath, 'r', encoding=encoding).read()
71
+ PrettyOutput.print(content, OutputType.INFO)
73
72
  return {
74
73
  "success": True,
75
74
  "stdout": content,
@@ -80,10 +79,10 @@ class FileOperationTool:
80
79
  if not args.get("content"):
81
80
  return {
82
81
  "success": False,
83
- "error": "写入/追加操作需要提供content参数"
82
+ "error": "Write/append operation requires providing the content parameter"
84
83
  }
85
84
 
86
- # 创建目录(如果不存在)
85
+ # Create directory (if it doesn't exist)
87
86
  os.makedirs(os.path.dirname(os.path.abspath(filepath)), exist_ok=True)
88
87
 
89
88
  mode = 'a' if operation == "append" else 'w'
@@ -92,19 +91,19 @@ class FileOperationTool:
92
91
 
93
92
  return {
94
93
  "success": True,
95
- "stdout": f"成功{operation}内容到 {filepath}",
94
+ "stdout": f"Successfully {operation} content to {filepath}",
96
95
  "stderr": ""
97
96
  }
98
97
 
99
98
  else:
100
99
  return {
101
100
  "success": False,
102
- "error": f"未知操作: {operation}"
101
+ "error": f"Unknown operation: {operation}"
103
102
  }
104
103
 
105
104
  except Exception as e:
106
105
  PrettyOutput.print(str(e), OutputType.ERROR)
107
106
  return {
108
107
  "success": False,
109
- "error": f"文件操作失败: {str(e)}"
108
+ "error": f"File operation failed: {str(e)}"
110
109
  }
@@ -0,0 +1,86 @@
1
+ import os
2
+ from typing import Any, Dict
3
+ from jarvis.jarvis_codebase.main import CodeBase
4
+ from jarvis.utils import find_git_root, PrettyOutput, OutputType
5
+
6
+ class CodebaseSearchTool:
7
+ """Codebase Search Tool"""
8
+
9
+ name = "find_related_files"
10
+ description = "Find code files related to the given requirement by searching the codebase using NLP-based semantic search. IMPORTANT: Requires complete sentence descriptions - keywords or phrases alone will not yield comprehensive results."
11
+ parameters = {
12
+ "type": "object",
13
+ "properties": {
14
+ "dir": {
15
+ "type": "string",
16
+ "description": "Project root directory"
17
+ },
18
+ "query": {
19
+ "type": "string",
20
+ "description": """Requirement description to find related code files. Must be a complete sentence that clearly describes what you're looking for.
21
+
22
+ Good examples:
23
+ - 'Need to modify the user authentication process to add password validation'
24
+ - 'Want to update the database connection configuration to support multiple databases'
25
+ - 'Looking for the code that handles file upload functionality in the system'
26
+
27
+ Bad examples (will not work well):
28
+ - 'user auth'
29
+ - 'database config'
30
+ - 'upload'""",
31
+ "examples": [
32
+ "Need to modify the error handling in the authentication process",
33
+ "Want to update how the system processes user uploads",
34
+ "Looking for the code that manages database connections"
35
+ ]
36
+ },
37
+ "top_k": {
38
+ "type": "integer",
39
+ "description": "Number of most relevant files to return",
40
+ "default": 5
41
+ }
42
+ },
43
+ "required": ["query"]
44
+ }
45
+
46
+ def execute(self, params: Dict[str, Any]) -> Dict[str, Any]:
47
+ """Execute codebase search"""
48
+ try:
49
+ dir = params.get("dir")
50
+ query = params["query"]
51
+ top_k = params.get("top_k", 5)
52
+
53
+ # Find the root directory of the codebase
54
+ current_dir = os.getcwd()
55
+ root_dir = find_git_root(dir or current_dir)
56
+ if not root_dir:
57
+ return {
58
+ "success": False,
59
+ "stdout": "",
60
+ "stderr": "Error: Current directory is not in a Git repository",
61
+ "error": "NotInGitRepository"
62
+ }
63
+
64
+ os.chdir(root_dir)
65
+ codebase = CodeBase(root_dir)
66
+ # Generate index
67
+
68
+ codebase.generate_codebase()
69
+ # Execute search
70
+ response = codebase.search_similar(query, top_k)
71
+ os.chdir(current_dir)
72
+ return {
73
+ "success": True,
74
+ "stdout": str(response),
75
+ "stderr": "",
76
+ "error": None
77
+ }
78
+
79
+ except Exception as e:
80
+ PrettyOutput.print(f"Codebase QA error: {str(e)}", output_type=OutputType.ERROR)
81
+ return {
82
+ "success": False,
83
+ "stdout": "",
84
+ "stderr": f"Error executing codebase QA: {str(e)}",
85
+ "error": str(type(e).__name__)
86
+ }