jarvis-ai-assistant 0.1.103__py3-none-any.whl → 0.1.105__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 (65) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/agent.py +124 -67
  3. jarvis/jarvis_code_agent/code_agent.py +133 -22
  4. jarvis/jarvis_code_agent/file_select.py +4 -6
  5. jarvis/jarvis_code_agent/patch.py +6 -7
  6. jarvis/jarvis_code_agent/relevant_files.py +163 -41
  7. jarvis/jarvis_codebase/main.py +43 -29
  8. jarvis/jarvis_lsp/base.py +143 -0
  9. jarvis/jarvis_lsp/cpp.py +134 -0
  10. jarvis/jarvis_lsp/go.py +140 -0
  11. jarvis/jarvis_lsp/python.py +135 -0
  12. jarvis/jarvis_lsp/registry.py +234 -0
  13. jarvis/jarvis_lsp/rust.py +142 -0
  14. jarvis/jarvis_platform/__init__.py +3 -0
  15. jarvis/{models → jarvis_platform}/ai8.py +1 -1
  16. jarvis/{models → jarvis_platform}/kimi.py +1 -1
  17. jarvis/{models → jarvis_platform}/ollama.py +1 -1
  18. jarvis/{models → jarvis_platform}/openai.py +1 -1
  19. jarvis/{models → jarvis_platform}/oyi.py +1 -1
  20. jarvis/{models → jarvis_platform}/registry.py +11 -11
  21. jarvis/{jarvis_platform → jarvis_platform_manager}/main.py +2 -2
  22. jarvis/jarvis_rag/main.py +8 -8
  23. jarvis/jarvis_smart_shell/main.py +3 -3
  24. jarvis/jarvis_tools/__init__.py +0 -0
  25. jarvis/{tools → jarvis_tools}/ask_codebase.py +1 -4
  26. jarvis/{tools → jarvis_tools}/ask_user.py +1 -1
  27. jarvis/{tools → jarvis_tools}/chdir.py +2 -37
  28. jarvis/jarvis_tools/code_review.py +236 -0
  29. jarvis/jarvis_tools/create_code_agent.py +115 -0
  30. jarvis/{tools → jarvis_tools}/create_sub_agent.py +1 -1
  31. jarvis/jarvis_tools/deep_thinking.py +160 -0
  32. jarvis/jarvis_tools/deep_thinking_agent.py +146 -0
  33. jarvis/{tools → jarvis_tools}/git_commiter.py +3 -3
  34. jarvis/jarvis_tools/lsp_find_definition.py +134 -0
  35. jarvis/jarvis_tools/lsp_find_references.py +111 -0
  36. jarvis/jarvis_tools/lsp_get_diagnostics.py +121 -0
  37. jarvis/jarvis_tools/lsp_get_document_symbols.py +87 -0
  38. jarvis/jarvis_tools/lsp_prepare_rename.py +130 -0
  39. jarvis/jarvis_tools/lsp_validate_edit.py +141 -0
  40. jarvis/{tools → jarvis_tools}/methodology.py +6 -1
  41. jarvis/{tools → jarvis_tools}/rag.py +1 -1
  42. jarvis/{tools → jarvis_tools}/read_code.py +0 -31
  43. jarvis/{tools → jarvis_tools}/registry.py +6 -5
  44. jarvis/{tools → jarvis_tools}/search.py +2 -2
  45. jarvis/utils.py +71 -28
  46. {jarvis_ai_assistant-0.1.103.dist-info → jarvis_ai_assistant-0.1.105.dist-info}/METADATA +98 -62
  47. jarvis_ai_assistant-0.1.105.dist-info/RECORD +62 -0
  48. {jarvis_ai_assistant-0.1.103.dist-info → jarvis_ai_assistant-0.1.105.dist-info}/entry_points.txt +4 -4
  49. jarvis/models/__init__.py +0 -3
  50. jarvis/tools/code_review.py +0 -163
  51. jarvis/tools/create_code_sub_agent.py +0 -30
  52. jarvis/tools/create_code_test_agent.py +0 -115
  53. jarvis/tools/create_ctags_agent.py +0 -176
  54. jarvis/tools/find_in_codebase.py +0 -108
  55. jarvis_ai_assistant-0.1.103.dist-info/RECORD +0 -51
  56. /jarvis/{models → jarvis_platform}/base.py +0 -0
  57. /jarvis/{tools → jarvis_platform_manager}/__init__.py +0 -0
  58. /jarvis/{tools → jarvis_tools}/base.py +0 -0
  59. /jarvis/{tools → jarvis_tools}/execute_shell.py +0 -0
  60. /jarvis/{tools → jarvis_tools}/file_operation.py +0 -0
  61. /jarvis/{tools → jarvis_tools}/read_webpage.py +0 -0
  62. /jarvis/{tools → jarvis_tools}/select_code_files.py +0 -0
  63. {jarvis_ai_assistant-0.1.103.dist-info → jarvis_ai_assistant-0.1.105.dist-info}/LICENSE +0 -0
  64. {jarvis_ai_assistant-0.1.103.dist-info → jarvis_ai_assistant-0.1.105.dist-info}/WHEEL +0 -0
  65. {jarvis_ai_assistant-0.1.103.dist-info → jarvis_ai_assistant-0.1.105.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,87 @@
1
+ import os
2
+ from typing import Dict, Any
3
+ from jarvis.jarvis_lsp.registry import LSPRegistry
4
+
5
+ class LSPGetDocumentSymbolsTool:
6
+ """Tool for getting document symbols in code files using LSP."""
7
+
8
+ name = "lsp_get_document_symbols"
9
+ description = "Get document symbols (functions, classes, variables) in code files"
10
+ parameters = {
11
+ "file_path": "Path to the file to analyze",
12
+ "language": f"Programming language of the file ({', '.join(LSPRegistry.get_global_lsp_registry().get_supported_languages())})"
13
+ }
14
+
15
+ @staticmethod
16
+ def check() -> bool:
17
+ """Check if any LSP server is available."""
18
+ registry = LSPRegistry.get_global_lsp_registry()
19
+ return len(registry.get_supported_languages()) > 0
20
+
21
+ def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
22
+ """Execute the tool."""
23
+ file_path = args.get("file_path", "")
24
+ language = args.get("language", "")
25
+
26
+ if not file_path or not language:
27
+ return {
28
+ "success": False,
29
+ "stderr": "Both file_path and language must be provided",
30
+ "stdout": ""
31
+ }
32
+
33
+ if not os.path.exists(file_path):
34
+ return {
35
+ "success": False,
36
+ "stderr": f"File not found: {file_path}",
37
+ "stdout": ""
38
+ }
39
+
40
+ # Get LSP instance
41
+ registry = LSPRegistry.get_global_lsp_registry()
42
+ lsp = registry.create_lsp(language)
43
+
44
+ if not lsp:
45
+ return {
46
+ "success": False,
47
+ "stderr": f"No LSP support for language: {language}",
48
+ "stdout": ""
49
+ }
50
+
51
+ try:
52
+ # Initialize LSP
53
+ if not lsp.initialize(os.path.dirname(os.path.abspath(file_path))):
54
+ return {
55
+ "success": False,
56
+ "stderr": "LSP initialization failed",
57
+ "stdout": ""
58
+ }
59
+
60
+ # Get symbols
61
+ symbols = lsp.get_document_symbols(file_path)
62
+
63
+ # Format output
64
+ output = []
65
+ for symbol in symbols:
66
+ start = symbol["range"]["start"]
67
+ name = LSPRegistry.get_text_at_position(file_path, start["line"], start["character"])
68
+ line = LSPRegistry.get_line_at_position(file_path, start["line"]).strip()
69
+ output.append(f"Symbol: {name}")
70
+ output.append(f"Line {start['line'] + 1}: {line}")
71
+ output.append("-" * 40)
72
+
73
+ return {
74
+ "success": True,
75
+ "stdout": "\n".join(output) if output else "No symbols found",
76
+ "stderr": ""
77
+ }
78
+
79
+ except Exception as e:
80
+ return {
81
+ "success": False,
82
+ "stderr": f"Error finding symbols: {str(e)}",
83
+ "stdout": ""
84
+ }
85
+ finally:
86
+ if lsp:
87
+ lsp.shutdown()
@@ -0,0 +1,130 @@
1
+ import os
2
+ from typing import Dict, Any
3
+ from jarvis.jarvis_lsp.registry import LSPRegistry
4
+
5
+ class LSPPrepareRenameTool:
6
+ """Tool for checking if a symbol can be renamed using LSP."""
7
+
8
+ name = "lsp_prepare_rename"
9
+ description = "Check if a symbol can be safely renamed and show all locations that would be affected"
10
+ parameters = {
11
+ "file_path": "Path to the file containing the symbol",
12
+ "line": "Line number (0-based) of the symbol",
13
+ "character": "Character position in the line",
14
+ "language": f"Programming language of the file ({', '.join(LSPRegistry.get_global_lsp_registry().get_supported_languages())})"
15
+ }
16
+
17
+ @staticmethod
18
+ def check() -> bool:
19
+ """Check if any LSP server is available."""
20
+ registry = LSPRegistry.get_global_lsp_registry()
21
+ return len(registry.get_supported_languages()) > 0
22
+
23
+ def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
24
+ """Execute the tool."""
25
+ file_path = args.get("file_path", "")
26
+ line = args.get("line", None)
27
+ character = args.get("character", None)
28
+ language = args.get("language", "")
29
+
30
+ # Validate inputs
31
+ if not all([file_path, line is not None, character is not None, language]):
32
+ return {
33
+ "success": False,
34
+ "stderr": "All parameters (file_path, line, character, language) must be provided",
35
+ "stdout": ""
36
+ }
37
+
38
+ try:
39
+ line = int(line)
40
+ character = int(character)
41
+ except ValueError:
42
+ return {
43
+ "success": False,
44
+ "stderr": "Line and character must be integers",
45
+ "stdout": ""
46
+ }
47
+
48
+ if not os.path.exists(file_path):
49
+ return {
50
+ "success": False,
51
+ "stderr": f"File not found: {file_path}",
52
+ "stdout": ""
53
+ }
54
+
55
+ # Get LSP instance
56
+ registry = LSPRegistry.get_global_lsp_registry()
57
+ lsp = registry.create_lsp(language)
58
+
59
+ if not lsp:
60
+ return {
61
+ "success": False,
62
+ "stderr": f"No LSP support for language: {language}",
63
+ "stdout": ""
64
+ }
65
+
66
+ try:
67
+ # Initialize LSP
68
+ if not lsp.initialize(os.path.dirname(os.path.abspath(file_path))):
69
+ return {
70
+ "success": False,
71
+ "stderr": "LSP initialization failed",
72
+ "stdout": ""
73
+ }
74
+
75
+ # Get symbol at position
76
+ symbol = LSPRegistry.get_text_at_position(file_path, line, character)
77
+ if not symbol:
78
+ return {
79
+ "success": False,
80
+ "stderr": f"No symbol found at position {line}:{character}",
81
+ "stdout": ""
82
+ }
83
+
84
+ # Check if rename is possible
85
+ rename_info = lsp.prepare_rename(file_path, (line, character))
86
+ if not rename_info:
87
+ return {
88
+ "success": True,
89
+ "stdout": f"Symbol '{symbol}' cannot be renamed. It might be:\n" +
90
+ "- A built-in or library symbol\n" +
91
+ "- A read-only symbol\n" +
92
+ "- Not a valid identifier",
93
+ "stderr": ""
94
+ }
95
+
96
+ # Get all references to show affected locations
97
+ refs = lsp.find_references(file_path, (line, character))
98
+
99
+ # Format output
100
+ output = [
101
+ f"Symbol '{symbol}' can be renamed.",
102
+ f"\nRenaming will affect the following locations:"
103
+ ]
104
+
105
+ for ref in refs:
106
+ ref_line = ref["range"]["start"]["line"]
107
+ ref_char = ref["range"]["start"]["character"]
108
+ context = LSPRegistry.get_line_at_position(ref["uri"], ref_line).strip()
109
+ output.extend([
110
+ f"\nFile: {ref['uri']}",
111
+ f"Line {ref_line + 1}, Col {ref_char + 1}: {context}"
112
+ ])
113
+
114
+ output.append("\nNote: Make sure to review all locations before performing the rename.")
115
+
116
+ return {
117
+ "success": True,
118
+ "stdout": "\n".join(output),
119
+ "stderr": ""
120
+ }
121
+
122
+ except Exception as e:
123
+ return {
124
+ "success": False,
125
+ "stderr": f"Error checking rename possibility: {str(e)}",
126
+ "stdout": ""
127
+ }
128
+ finally:
129
+ if lsp:
130
+ lsp.shutdown()
@@ -0,0 +1,141 @@
1
+ import os
2
+ from typing import Dict, Any
3
+ from jarvis.jarvis_lsp.registry import LSPRegistry
4
+
5
+ class LSPValidateEditTool:
6
+ """Tool for validating code edits using LSP."""
7
+
8
+ name = "lsp_validate_edit"
9
+ description = "Validate if a proposed code edit is syntactically correct"
10
+ parameters = {
11
+ "file_path": "Path to the file to edit",
12
+ "start_line": "Starting line number (0-based) of the edit",
13
+ "start_character": "Starting character position in the start line",
14
+ "end_line": "Ending line number (0-based) of the edit",
15
+ "end_character": "Ending character position in the end line",
16
+ "new_text": "New text to insert",
17
+ "language": f"Programming language of the file ({', '.join(LSPRegistry.get_global_lsp_registry().get_supported_languages())})"
18
+ }
19
+
20
+ @staticmethod
21
+ def check() -> bool:
22
+ """Check if any LSP server is available."""
23
+ registry = LSPRegistry.get_global_lsp_registry()
24
+ return len(registry.get_supported_languages()) > 0
25
+
26
+ def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
27
+ """Execute the tool."""
28
+ file_path = args.get("file_path", "")
29
+ start_line = args.get("start_line", None)
30
+ start_character = args.get("start_character", None)
31
+ end_line = args.get("end_line", None)
32
+ end_character = args.get("end_character", None)
33
+ new_text = args.get("new_text", "")
34
+ language = args.get("language", "")
35
+
36
+ # Validate inputs
37
+ if not all([file_path, start_line is not None, start_character is not None,
38
+ end_line is not None, end_character is not None, language]):
39
+ return {
40
+ "success": False,
41
+ "stderr": "All parameters except new_text must be provided",
42
+ "stdout": ""
43
+ }
44
+
45
+ try:
46
+ start_line = int(start_line)
47
+ start_character = int(start_character)
48
+ end_line = int(end_line)
49
+ end_character = int(end_character)
50
+ except ValueError:
51
+ return {
52
+ "success": False,
53
+ "stderr": "Line and character positions must be integers",
54
+ "stdout": ""
55
+ }
56
+
57
+ if not os.path.exists(file_path):
58
+ return {
59
+ "success": False,
60
+ "stderr": f"File not found: {file_path}",
61
+ "stdout": ""
62
+ }
63
+
64
+ # Get LSP instance
65
+ registry = LSPRegistry.get_global_lsp_registry()
66
+ lsp = registry.create_lsp(language)
67
+
68
+ if not lsp:
69
+ return {
70
+ "success": False,
71
+ "stderr": f"No LSP support for language: {language}",
72
+ "stdout": ""
73
+ }
74
+
75
+ try:
76
+ # Initialize LSP
77
+ if not lsp.initialize(os.path.dirname(os.path.abspath(file_path))):
78
+ return {
79
+ "success": False,
80
+ "stderr": "LSP initialization failed",
81
+ "stdout": ""
82
+ }
83
+
84
+ # Prepare edit operation
85
+ edit = {
86
+ "range": {
87
+ "start": {"line": start_line, "character": start_character},
88
+ "end": {"line": end_line, "character": end_character}
89
+ },
90
+ "newText": new_text
91
+ }
92
+
93
+ # Show the edit preview
94
+ output = ["Edit Preview:"]
95
+
96
+ # Show original code
97
+ try:
98
+ with open(file_path, 'r') as f:
99
+ lines = f.readlines()
100
+ context_start = max(0, start_line - 2)
101
+ context_end = min(len(lines), end_line + 3)
102
+
103
+ output.append("\nOriginal code:")
104
+ for i in range(context_start, context_end):
105
+ prefix = ">" if start_line <= i <= end_line else " "
106
+ output.append(f"{prefix} {i+1:4d} | {lines[i].rstrip()}")
107
+ except Exception:
108
+ pass
109
+
110
+ # Show new text
111
+ output.extend([
112
+ "\nNew text to insert:",
113
+ new_text,
114
+ "\nEdit range:",
115
+ f"From line {start_line + 1}, character {start_character}",
116
+ f"To line {end_line + 1}, character {end_character}"
117
+ ])
118
+
119
+ # Validate edit
120
+ is_valid = lsp.validate_edit(file_path, edit)
121
+
122
+ if is_valid:
123
+ output.append("\nValidation Result: The edit is syntactically correct ✓")
124
+ else:
125
+ output.append("\nValidation Result: The edit would introduce syntax errors ✗")
126
+
127
+ return {
128
+ "success": True,
129
+ "stdout": "\n".join(output),
130
+ "stderr": ""
131
+ }
132
+
133
+ except Exception as e:
134
+ return {
135
+ "success": False,
136
+ "stderr": f"Error validating edit: {str(e)}",
137
+ "stdout": ""
138
+ }
139
+ finally:
140
+ if lsp:
141
+ lsp.shutdown()
@@ -1,7 +1,7 @@
1
1
  import os
2
2
  import yaml
3
3
  from typing import Dict, Optional, Any
4
- from jarvis.utils import OutputType, PrettyOutput
4
+ from jarvis.utils import OutputType, PrettyOutput, is_use_methodology
5
5
 
6
6
 
7
7
  class MethodologyTool:
@@ -29,6 +29,11 @@ class MethodologyTool:
29
29
  },
30
30
  "required": ["operation", "problem_type"]
31
31
  }
32
+
33
+ @staticmethod
34
+ def check()->bool:
35
+ """Check if the methodology is enabled"""
36
+ return is_use_methodology()
32
37
 
33
38
  def __init__(self):
34
39
  """Initialize the experience management tool"""
@@ -133,7 +133,7 @@ def main():
133
133
  })
134
134
 
135
135
  if result["success"]:
136
- PrettyOutput.print(f"Answer: {result['stdout']}", OutputType.INFO)
136
+ PrettyOutput.print(f"{result['stdout']}", OutputType.INFO, lang="markdown")
137
137
  else:
138
138
  PrettyOutput.print(result["stderr"], OutputType.ERROR)
139
139
 
@@ -114,34 +114,3 @@ class ReadCodeTool:
114
114
  "stdout": "",
115
115
  "stderr": f"Failed to read code: {str(e)}"
116
116
  }
117
-
118
-
119
- def main():
120
- """Command line interface for the tool"""
121
- import argparse
122
-
123
- parser = argparse.ArgumentParser(description='Read code file with line numbers')
124
- parser.add_argument('filepath', help='Path to the code file')
125
- parser.add_argument('--start', type=int, default=0, help='Start line number (0-based)')
126
- parser.add_argument('--end', type=int, default=-1, help='End line number (0-based)')
127
-
128
- args = parser.parse_args()
129
-
130
- tool = ReadCodeTool()
131
- result = tool.execute({
132
- "filepath": args.filepath,
133
- "start_line": args.start,
134
- "end_line": args.end
135
- })
136
-
137
- if result["success"]:
138
- print(result["stdout"])
139
- else:
140
- PrettyOutput.print(result["stderr"], OutputType.ERROR)
141
- return 1
142
-
143
- return 0
144
-
145
-
146
- if __name__ == "__main__":
147
- main()
@@ -3,12 +3,12 @@ from pathlib import Path
3
3
  import sys
4
4
  from typing import Any, Callable, Dict, List, Optional
5
5
 
6
- from jarvis.models.registry import PlatformRegistry
7
- from jarvis.tools.base import Tool
6
+ from jarvis.jarvis_platform.registry import PlatformRegistry
7
+ from jarvis.jarvis_tools.base import Tool
8
8
  from jarvis.utils import OutputType, PrettyOutput, get_max_context_length
9
9
 
10
10
 
11
- tool_call_help = """Tool Usage Format:
11
+ tool_call_help = """## Tool Usage Format
12
12
 
13
13
  <TOOL_CALL>
14
14
  name: tool_name
@@ -49,7 +49,7 @@ class ToolRegistry:
49
49
  """Load tools"""
50
50
  tools = self.get_all_tools()
51
51
  if tools:
52
- tools_prompt = "Available tools:\n"
52
+ tools_prompt = "## Available tools:\n"
53
53
  for tool in tools:
54
54
  tools_prompt += f"- Name: {tool['name']}\n"
55
55
  tools_prompt += f" Description: {tool['description']}\n"
@@ -136,7 +136,8 @@ class ToolRegistry:
136
136
  if (isinstance(item, type) and
137
137
  hasattr(item, 'name') and
138
138
  hasattr(item, 'description') and
139
- hasattr(item, 'parameters')):
139
+ hasattr(item, 'parameters') and
140
+ hasattr(item, 'execute')):
140
141
 
141
142
  if hasattr(item, "check"):
142
143
  if not item.check():
@@ -1,7 +1,7 @@
1
1
  from typing import Dict, Any, List
2
- from jarvis.models.registry import PlatformRegistry
2
+ from jarvis.jarvis_platform.registry import PlatformRegistry
3
3
  from jarvis.utils import PrettyOutput, OutputType
4
- from jarvis.tools.read_webpage import WebpageTool
4
+ from jarvis.jarvis_tools.read_webpage import WebpageTool
5
5
  from playwright.sync_api import sync_playwright
6
6
  from urllib.parse import quote
7
7
 
jarvis/utils.py CHANGED
@@ -4,7 +4,7 @@ import time
4
4
  import os
5
5
  from enum import Enum
6
6
  from datetime import datetime
7
- from typing import Any, Dict
7
+ from typing import Any, Dict, Optional
8
8
  import colorama
9
9
  from colorama import Fore, Style as ColoramaStyle
10
10
  import numpy as np
@@ -85,7 +85,7 @@ class PrettyOutput:
85
85
  """Pretty output using rich"""
86
86
 
87
87
  # Icons for different output types
88
- ICONS = {
88
+ _ICONS = {
89
89
  OutputType.SYSTEM: "🤖", # Robot - AI assistant
90
90
  OutputType.CODE: "📝", # Notebook - Code
91
91
  OutputType.RESULT: "✨", # Flash - Result
@@ -147,7 +147,7 @@ class PrettyOutput:
147
147
  return default_lang
148
148
 
149
149
  @staticmethod
150
- def format(text: str, output_type: OutputType, timestamp: bool = True) -> Text:
150
+ def _format(text: str, output_type: OutputType, timestamp: bool = True) -> Text:
151
151
  """Format output text using rich Text"""
152
152
  # Create rich Text object
153
153
  formatted = Text()
@@ -157,17 +157,17 @@ class PrettyOutput:
157
157
  formatted.append(f"[{datetime.now().strftime('%H:%M:%S')}] ", style="white")
158
158
  formatted.append(f"[{get_agent_list()}]", style="blue")
159
159
  # Add icon
160
- icon = PrettyOutput.ICONS.get(output_type, "")
160
+ icon = PrettyOutput._ICONS.get(output_type, "")
161
161
  formatted.append(f"{icon} ", style=output_type.value)
162
162
 
163
163
  return formatted
164
164
 
165
165
  @staticmethod
166
- def print(text: str, output_type: OutputType, timestamp: bool = True):
166
+ def print(text: str, output_type: OutputType, timestamp: bool = True, lang: Optional[str] = None):
167
167
  """Print formatted output using rich console"""
168
168
  # Get formatted header
169
- lang = PrettyOutput._detect_language(text, default_lang='markdown')
170
- header = PrettyOutput.format("", output_type, timestamp)
169
+ lang = lang if lang is not None else PrettyOutput._detect_language(text, default_lang='markdown')
170
+ header = PrettyOutput._format("", output_type, timestamp)
171
171
 
172
172
  content = Syntax(text, lang, theme="monokai")
173
173
 
@@ -208,14 +208,6 @@ def get_single_line_input(tip: str) -> str:
208
208
  })
209
209
  return session.prompt(f"{tip}", style=style)
210
210
 
211
- def make_choice_input(tip: str, choices: list) -> str:
212
- """Get choice input, support direction key, history function, etc."""
213
- session = PromptSession(history=None)
214
- style = PromptStyle.from_dict({
215
- 'prompt': 'ansicyan',
216
- })
217
- return session.prompt(f"{tip}", style=style)
218
-
219
211
  class FileCompleter(Completer):
220
212
  """Custom completer for file paths with fuzzy matching."""
221
213
  def __init__(self):
@@ -341,7 +333,7 @@ def init_env():
341
333
  with open(env_file, "r", encoding="utf-8") as f:
342
334
  for line in f:
343
335
  line = line.strip()
344
- if line and not line.startswith("#"):
336
+ if line and not line.startswith(("#", ";")):
345
337
  try:
346
338
  key, value = line.split("=", 1)
347
339
  os.environ[key.strip()] = value.strip().strip("'").strip('"')
@@ -445,8 +437,7 @@ def load_rerank_model():
445
437
 
446
438
  return model, tokenizer
447
439
 
448
- def get_max_context_length():
449
- return int(os.getenv('JARVIS_MAX_CONTEXT_LENGTH', '131072')) # 默认128k
440
+
450
441
 
451
442
  def is_long_context(files: list) -> bool:
452
443
  """Check if the file list belongs to a long context (total characters exceed 80% of the maximum context length)"""
@@ -468,15 +459,12 @@ def is_long_context(files: list) -> bool:
468
459
 
469
460
  return total_chars > threshold
470
461
 
471
- def get_thread_count():
472
- return int(os.getenv('JARVIS_THREAD_COUNT', '1'))
462
+
473
463
 
474
464
  def get_file_md5(filepath: str)->str:
475
465
  return hashlib.md5(open(filepath, "rb").read(100*1024*1024)).hexdigest()
476
466
 
477
467
 
478
- def dont_use_local_model():
479
- return os.getenv('JARVIS_DONT_USE_LOCAL_MODEL', 'false') == 'true'
480
468
 
481
469
 
482
470
  def _create_methodology_embedding(embedding_model: Any, methodology_text: str) -> np.ndarray:
@@ -576,12 +564,7 @@ def load_methodology(user_input: str) -> str:
576
564
  import traceback
577
565
  PrettyOutput.print(f"Error trace: {traceback.format_exc()}", OutputType.INFO)
578
566
  return ""
579
-
580
- def is_auto_complete() -> bool:
581
- return os.getenv('JARVIS_AUTO_COMPLETE', 'false') == 'true'
582
567
 
583
- def is_disable_codebase() -> bool:
584
- return os.getenv('JARVIS_DISABLE_CODEBASE', 'false') == 'true'
585
568
 
586
569
  def user_confirm(tip: str, default: bool = True) -> bool:
587
570
  """Prompt the user for confirmation.
@@ -601,4 +584,64 @@ def get_file_line_count(filename: str) -> int:
601
584
  try:
602
585
  return len(open(filename, "r", encoding="utf-8").readlines())
603
586
  except Exception as e:
604
- return 0
587
+ return 0
588
+
589
+ def get_max_context_length():
590
+ return int(os.getenv('JARVIS_MAX_CONTEXT_LENGTH', '131072')) # 默认128k
591
+
592
+ def get_thread_count():
593
+ return int(os.getenv('JARVIS_THREAD_COUNT', '1'))
594
+
595
+ def dont_use_local_model():
596
+ return os.getenv('JARVIS_DONT_USE_LOCAL_MODEL', 'false') == 'true'
597
+
598
+ def is_auto_complete() -> bool:
599
+ return os.getenv('JARVIS_AUTO_COMPLETE', 'false') == 'true'
600
+
601
+ def is_disable_codebase() -> bool:
602
+ return os.getenv('JARVIS_DISABLE_CODEBASE', 'false') == 'true'
603
+
604
+ def is_use_methodology() -> bool:
605
+ return os.getenv('JARVIS_USE_METHODOLOGY', 'true') == 'true'
606
+
607
+ def is_record_methodology() -> bool:
608
+ return os.getenv('JARVIS_RECORD_METHODOLOGY', 'true') == 'true'
609
+
610
+ def is_need_summary() -> bool:
611
+ return os.getenv('JARVIS_NEED_SUMMARY', 'true') == 'true'
612
+
613
+ def get_min_paragraph_length() -> int:
614
+ return int(os.getenv('JARVIS_MIN_PARAGRAPH_LENGTH', '50'))
615
+
616
+ def get_max_paragraph_length() -> int:
617
+ return int(os.getenv('JARVIS_MAX_PARAGRAPH_LENGTH', '1000'))
618
+
619
+ def get_context_window() -> int:
620
+ return int(os.getenv('JARVIS_CONTEXT_WINDOW', '5'))
621
+
622
+ def get_shell_name() -> str:
623
+ return os.getenv('SHELL', 'bash')
624
+
625
+ def get_normal_platform_name() -> str:
626
+ return os.getenv('JARVIS_PLATFORM', 'kimi')
627
+
628
+ def get_normal_model_name() -> str:
629
+ return os.getenv('JARVIS_MODEL', 'kimi')
630
+
631
+ def get_codegen_platform_name() -> str:
632
+ return os.getenv('JARVIS_CODEGEN_PLATFORM', os.getenv('JARVIS_PLATFORM', 'kimi'))
633
+
634
+ def get_codegen_model_name() -> str:
635
+ return os.getenv('JARVIS_CODEGEN_MODEL', os.getenv('JARVIS_MODEL', 'kimi'))
636
+
637
+ def get_thinking_platform_name() -> str:
638
+ return os.getenv('JARVIS_THINKING_PLATFORM', os.getenv('JARVIS_PLATFORM', 'kimi'))
639
+
640
+ def get_thinking_model_name() -> str:
641
+ return os.getenv('JARVIS_THINKING_MODEL', os.getenv('JARVIS_MODEL', 'kimi'))
642
+
643
+ def get_cheap_platform_name() -> str:
644
+ return os.getenv('JARVIS_CHEAP_PLATFORM', os.getenv('JARVIS_PLATFORM', 'kimi'))
645
+
646
+ def get_cheap_model_name() -> str:
647
+ return os.getenv('JARVIS_CHEAP_MODEL', os.getenv('JARVIS_MODEL', 'kimi'))