jarvis-ai-assistant 0.1.97__py3-none-any.whl → 0.1.98__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.
- jarvis/__init__.py +1 -1
- jarvis/jarvis_coder/git_utils.py +18 -18
- jarvis/jarvis_coder/main.py +150 -150
- jarvis/jarvis_coder/patch_handler.py +38 -38
- jarvis/jarvis_coder/plan_generator.py +21 -21
- jarvis/jarvis_platform/main.py +38 -38
- jarvis/jarvis_rag/main.py +181 -181
- jarvis/jarvis_smart_shell/main.py +19 -19
- {jarvis_ai_assistant-0.1.97.dist-info → jarvis_ai_assistant-0.1.98.dist-info}/METADATA +1 -1
- {jarvis_ai_assistant-0.1.97.dist-info → jarvis_ai_assistant-0.1.98.dist-info}/RECORD +14 -14
- {jarvis_ai_assistant-0.1.97.dist-info → jarvis_ai_assistant-0.1.98.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.97.dist-info → jarvis_ai_assistant-0.1.98.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.97.dist-info → jarvis_ai_assistant-0.1.98.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.97.dist-info → jarvis_ai_assistant-0.1.98.dist-info}/top_level.txt +0 -0
|
@@ -15,13 +15,13 @@ class PatchHandler:
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
def _extract_patches(self, response: str) -> List[Patch]:
|
|
18
|
-
"""
|
|
18
|
+
"""Extract patches from response
|
|
19
19
|
|
|
20
20
|
Args:
|
|
21
|
-
response:
|
|
21
|
+
response: Model response content
|
|
22
22
|
|
|
23
23
|
Returns:
|
|
24
|
-
List[Tuple[str, str, str]]:
|
|
24
|
+
List[Tuple[str, str, str]]: Patch list, each patch is a tuple of (format, file path, patch content)
|
|
25
25
|
"""
|
|
26
26
|
# 修改后的正则表达式匹配三种补丁格式
|
|
27
27
|
fmt_pattern = r'<PATCH>\n>>>>>> SEARCH\n(.*?)\n?(={5,})\n(.*?)\n?<<<<<< REPLACE\n</PATCH>'
|
|
@@ -32,21 +32,21 @@ class PatchHandler:
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
def _confirm_and_apply_changes(self, file_path: str) -> bool:
|
|
35
|
-
"""
|
|
35
|
+
"""Confirm and apply changes"""
|
|
36
36
|
os.system(f"git diff --cached {file_path}")
|
|
37
|
-
confirm = input(f"\
|
|
37
|
+
confirm = input(f"\nAccept {file_path} changes? (y/n) [y]: ").lower() or "y"
|
|
38
38
|
if confirm == "y":
|
|
39
39
|
return True
|
|
40
40
|
else:
|
|
41
|
-
#
|
|
41
|
+
# Rollback changes
|
|
42
42
|
os.system(f"git reset {file_path}")
|
|
43
43
|
os.system(f"git checkout -- {file_path}")
|
|
44
|
-
PrettyOutput.print(f"
|
|
44
|
+
PrettyOutput.print(f"Changes to {file_path} have been rolled back", OutputType.WARNING)
|
|
45
45
|
return False
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
def apply_file_patch(self, file_path: str, patches: List[Patch]) -> bool:
|
|
49
|
-
"""
|
|
49
|
+
"""Apply file patch"""
|
|
50
50
|
if not os.path.exists(file_path):
|
|
51
51
|
base_dir = os.path.dirname(file_path)
|
|
52
52
|
os.makedirs(base_dir, exist_ok=True)
|
|
@@ -54,20 +54,20 @@ class PatchHandler:
|
|
|
54
54
|
file_content = open(file_path, "r", encoding="utf-8").read()
|
|
55
55
|
for i, patch in enumerate(patches):
|
|
56
56
|
if patch.old_code == "" and patch.new_code == "":
|
|
57
|
-
PrettyOutput.print(f"
|
|
57
|
+
PrettyOutput.print(f"Apply patch {i+1}/{len(patches)}: Delete file {file_path}", OutputType.INFO)
|
|
58
58
|
file_content = ""
|
|
59
59
|
os.system(f"git rm {file_path}")
|
|
60
|
-
PrettyOutput.print(f"
|
|
60
|
+
PrettyOutput.print(f"Apply patch {i+1}/{len(patches)} successfully", OutputType.SUCCESS)
|
|
61
61
|
elif patch.old_code == "":
|
|
62
|
-
PrettyOutput.print(f"
|
|
62
|
+
PrettyOutput.print(f"Apply patch {i+1}/{len(patches)}: Replace file {file_path} content: \n{patch.new_code}", OutputType.INFO)
|
|
63
63
|
file_content = patch.new_code
|
|
64
64
|
open(file_path, "w", encoding="utf-8").write(patch.new_code)
|
|
65
65
|
os.system(f"git add {file_path}")
|
|
66
|
-
PrettyOutput.print(f"
|
|
66
|
+
PrettyOutput.print(f"Apply patch {i+1}/{len(patches)} successfully", OutputType.SUCCESS)
|
|
67
67
|
else:
|
|
68
|
-
PrettyOutput.print(f"
|
|
68
|
+
PrettyOutput.print(f"Apply patch {i+1}/{len(patches)}: File original content: \n{patch.old_code}\nReplace with: \n{patch.new_code}", OutputType.INFO)
|
|
69
69
|
if file_content.find(patch.old_code) == -1:
|
|
70
|
-
PrettyOutput.print(f"
|
|
70
|
+
PrettyOutput.print(f"File {file_path} does not contain {patch.old_code}", OutputType.WARNING)
|
|
71
71
|
os.system(f"git reset {file_path}")
|
|
72
72
|
os.system(f"git checkout -- {file_path}")
|
|
73
73
|
return False
|
|
@@ -75,20 +75,20 @@ class PatchHandler:
|
|
|
75
75
|
file_content = file_content.replace(patch.old_code, patch.new_code, 1)
|
|
76
76
|
open(file_path, "w", encoding="utf-8").write(file_content)
|
|
77
77
|
os.system(f"git add {file_path}")
|
|
78
|
-
PrettyOutput.print(f"
|
|
78
|
+
PrettyOutput.print(f"Apply patch {i+1}/{len(patches)} successfully", OutputType.SUCCESS)
|
|
79
79
|
return True
|
|
80
80
|
|
|
81
81
|
|
|
82
|
-
def retry_comfirm(self) -> Tuple[str, str]:#
|
|
83
|
-
choice = input("\
|
|
82
|
+
def retry_comfirm(self) -> Tuple[str, str]:# Restore user selection logic
|
|
83
|
+
choice = input("\nPlease choose an action: (1) Retry (2) Skip (3) Completely stop [1]: ") or "1"
|
|
84
84
|
if choice == "2":
|
|
85
85
|
return "skip", ""
|
|
86
86
|
if choice == "3":
|
|
87
87
|
return "break", ""
|
|
88
|
-
return "continue", get_multiline_input("
|
|
88
|
+
return "continue", get_multiline_input("Please enter additional information and requirements:")
|
|
89
89
|
|
|
90
90
|
def apply_patch(self, feature: str, raw_plan: str, structed_plan: Dict[str, str]) -> Tuple[bool, str]:
|
|
91
|
-
"""
|
|
91
|
+
"""Apply patch (main entry)"""
|
|
92
92
|
for file_path, current_plan in structed_plan.items():
|
|
93
93
|
additional_info = ""
|
|
94
94
|
while True:
|
|
@@ -96,7 +96,7 @@ class PatchHandler:
|
|
|
96
96
|
if os.path.exists(file_path):
|
|
97
97
|
content = open(file_path, "r", encoding="utf-8").read()
|
|
98
98
|
else:
|
|
99
|
-
content = "
|
|
99
|
+
content = "<File does not exist, need to create>"
|
|
100
100
|
prompt = """You are a senior software development expert who can generate code patches based on the complete modification plan, current original code file path, code content, and current file's modification plan. The output format should be as follows:
|
|
101
101
|
<PATCH>
|
|
102
102
|
>>>>>> SEARCH
|
|
@@ -135,20 +135,20 @@ class PatchHandler:
|
|
|
135
135
|
"""
|
|
136
136
|
|
|
137
137
|
|
|
138
|
-
PrettyOutput.print(f"
|
|
138
|
+
PrettyOutput.print(f"Generating formatted patches for {file_path}...", OutputType.PROGRESS)
|
|
139
139
|
response = PlatformRegistry.get_global_platform_registry().get_codegen_platform().chat_until_success(prompt)
|
|
140
140
|
patches = self._extract_patches(response)
|
|
141
141
|
|
|
142
142
|
if not patches or not self.apply_file_patch(file_path, patches) or not self._confirm_and_apply_changes(file_path):
|
|
143
143
|
os.system(f"git reset {file_path}")
|
|
144
144
|
os.system(f"git checkout -- {file_path}")
|
|
145
|
-
PrettyOutput.print("
|
|
145
|
+
PrettyOutput.print("Patch generation failed", OutputType.WARNING)
|
|
146
146
|
act, msg = self.retry_comfirm()
|
|
147
147
|
if act == "break":
|
|
148
|
-
PrettyOutput.print("
|
|
148
|
+
PrettyOutput.print("Terminate patch application", OutputType.WARNING)
|
|
149
149
|
return False, msg
|
|
150
150
|
if act == "skip":
|
|
151
|
-
PrettyOutput.print(f"
|
|
151
|
+
PrettyOutput.print(f"Skip file {file_path}", OutputType.WARNING)
|
|
152
152
|
break
|
|
153
153
|
else:
|
|
154
154
|
additional_info += msg + "\n"
|
|
@@ -161,31 +161,31 @@ class PatchHandler:
|
|
|
161
161
|
|
|
162
162
|
|
|
163
163
|
def handle_patch_application(self, feature: str, raw_plan: str, structed_plan: Dict[str,str]) -> bool:
|
|
164
|
-
"""
|
|
164
|
+
"""Process patch application process
|
|
165
165
|
|
|
166
166
|
Args:
|
|
167
|
-
related_files:
|
|
168
|
-
feature:
|
|
169
|
-
modification_plan:
|
|
167
|
+
related_files: Related files list
|
|
168
|
+
feature: Feature description
|
|
169
|
+
modification_plan: Modification plan
|
|
170
170
|
|
|
171
171
|
Returns:
|
|
172
|
-
bool:
|
|
172
|
+
bool: Whether patch application is successful
|
|
173
173
|
"""
|
|
174
|
-
PrettyOutput.print("\
|
|
174
|
+
PrettyOutput.print("\nThe following modification plan will be applied:", OutputType.INFO)
|
|
175
175
|
for file_path, patches_code in structed_plan.items():
|
|
176
|
-
PrettyOutput.print(f"\
|
|
177
|
-
PrettyOutput.print(f"
|
|
178
|
-
# 3.
|
|
176
|
+
PrettyOutput.print(f"\nFile: {file_path}", OutputType.INFO)
|
|
177
|
+
PrettyOutput.print(f"Modification plan: \n{patches_code}", OutputType.INFO)
|
|
178
|
+
# 3. Apply patches
|
|
179
179
|
success, error_msg = self.apply_patch(feature, raw_plan, structed_plan)
|
|
180
180
|
if not success:
|
|
181
181
|
os.system("git reset --hard")
|
|
182
182
|
return False
|
|
183
|
-
# 6.
|
|
184
|
-
PrettyOutput.print("\
|
|
185
|
-
confirm = input("\
|
|
183
|
+
# 6. Apply successfully, let user confirm changes
|
|
184
|
+
PrettyOutput.print("\nPatches applied, please check the modification effect.", OutputType.SUCCESS)
|
|
185
|
+
confirm = input("\nKeep these changes? (y/n) [y]: ").lower() or "y"
|
|
186
186
|
if confirm != "y":
|
|
187
|
-
PrettyOutput.print("
|
|
188
|
-
os.system("git reset --hard") #
|
|
187
|
+
PrettyOutput.print("User cancelled changes, rolling back", OutputType.WARNING)
|
|
188
|
+
os.system("git reset --hard") # Rollback all changes
|
|
189
189
|
return False
|
|
190
190
|
else:
|
|
191
191
|
return True
|
|
@@ -4,18 +4,18 @@ from jarvis.models.registry import PlatformRegistry
|
|
|
4
4
|
from jarvis.utils import PrettyOutput, OutputType, get_multiline_input
|
|
5
5
|
|
|
6
6
|
class PlanGenerator:
|
|
7
|
-
"""
|
|
7
|
+
"""Modification plan generator"""
|
|
8
8
|
|
|
9
9
|
def _build_prompt(self, feature: str, related_files: List[Dict], additional_info: str) -> str:
|
|
10
|
-
"""
|
|
10
|
+
"""Build prompt
|
|
11
11
|
|
|
12
12
|
Args:
|
|
13
|
-
feature:
|
|
14
|
-
related_files:
|
|
15
|
-
additional_info:
|
|
13
|
+
feature: Feature description
|
|
14
|
+
related_files: Related files list
|
|
15
|
+
additional_info: User supplement information
|
|
16
16
|
|
|
17
17
|
Returns:
|
|
18
|
-
str:
|
|
18
|
+
str: Complete prompt
|
|
19
19
|
"""
|
|
20
20
|
prompt = "You are a code modification expert who can generate modification plans based on requirements and relevant code snippets. I need your help to analyze how to implement the following feature:\n\n"
|
|
21
21
|
prompt += f"{feature}\n\n"
|
|
@@ -49,37 +49,37 @@ class PlanGenerator:
|
|
|
49
49
|
|
|
50
50
|
|
|
51
51
|
def generate_plan(self, feature: str, related_files: List[Dict]) -> Tuple[str, Dict[str,str]]:
|
|
52
|
-
"""
|
|
52
|
+
"""Generate modification plan
|
|
53
53
|
|
|
54
54
|
Args:
|
|
55
|
-
feature:
|
|
56
|
-
related_files:
|
|
55
|
+
feature: Feature description
|
|
56
|
+
related_files: Related files list
|
|
57
57
|
|
|
58
58
|
Returns:
|
|
59
|
-
Tuple[str, Dict[str,str]]:
|
|
59
|
+
Tuple[str, Dict[str,str]]: Modification plan, return None if user cancels
|
|
60
60
|
"""
|
|
61
61
|
additional_info = ""
|
|
62
62
|
while True:
|
|
63
63
|
prompt = self._build_prompt(feature, related_files, additional_info)
|
|
64
|
-
#
|
|
65
|
-
PrettyOutput.print("
|
|
64
|
+
# Build prompt
|
|
65
|
+
PrettyOutput.print("Start generating modification plan...", OutputType.PROGRESS)
|
|
66
66
|
|
|
67
|
-
#
|
|
67
|
+
# Get modification plan
|
|
68
68
|
raw_plan = PlatformRegistry.get_global_platform_registry().get_thinking_platform().chat_until_success(prompt)
|
|
69
69
|
structed_plan = self._extract_code(raw_plan)
|
|
70
70
|
if not structed_plan:
|
|
71
|
-
PrettyOutput.print("
|
|
72
|
-
tmp = get_multiline_input("
|
|
71
|
+
PrettyOutput.print("Modification plan generation failed, please try again", OutputType.ERROR)
|
|
72
|
+
tmp = get_multiline_input("Please enter your additional information or suggestions (press Enter to cancel):")
|
|
73
73
|
if tmp == "__interrupt__" or prompt == "":
|
|
74
74
|
return "", {}
|
|
75
75
|
additional_info += tmp + "\n"
|
|
76
76
|
continue
|
|
77
|
-
user_input = input("\
|
|
77
|
+
user_input = input("\nDo you agree with this modification plan? (y/n) [y]: ").strip().lower() or 'y'
|
|
78
78
|
if user_input == 'y' or user_input == '':
|
|
79
79
|
return raw_plan, structed_plan
|
|
80
80
|
elif user_input == 'n':
|
|
81
|
-
#
|
|
82
|
-
tmp = get_multiline_input("
|
|
81
|
+
# Get user feedback
|
|
82
|
+
tmp = get_multiline_input("Please enter your additional information or suggestions (press Enter to cancel):")
|
|
83
83
|
if prompt == "__interrupt__" or prompt == "":
|
|
84
84
|
return "", {}
|
|
85
85
|
additional_info += tmp + "\n"
|
|
@@ -87,13 +87,13 @@ class PlanGenerator:
|
|
|
87
87
|
|
|
88
88
|
|
|
89
89
|
def _extract_code(self, response: str) -> Dict[str, str]:
|
|
90
|
-
"""
|
|
90
|
+
"""Extract code from response
|
|
91
91
|
|
|
92
92
|
Args:
|
|
93
|
-
response:
|
|
93
|
+
response: Model response content
|
|
94
94
|
|
|
95
95
|
Returns:
|
|
96
|
-
Dict[str, List[str]]:
|
|
96
|
+
Dict[str, List[str]]: Code dictionary, key is file path, value is code snippet list
|
|
97
97
|
"""
|
|
98
98
|
code_dict = {}
|
|
99
99
|
for match in re.finditer(r'<PLAN>\n> (.+?)\n(.*?)\n</PLAN>', response, re.DOTALL):
|
jarvis/jarvis_platform/main.py
CHANGED
|
@@ -2,26 +2,26 @@ from jarvis.models.registry import PlatformRegistry
|
|
|
2
2
|
from jarvis.utils import PrettyOutput, OutputType, load_env_from_file, get_multiline_input
|
|
3
3
|
|
|
4
4
|
def list_platforms():
|
|
5
|
-
"""
|
|
5
|
+
"""List all supported platforms and models"""
|
|
6
6
|
registry = PlatformRegistry.get_global_platform_registry()
|
|
7
7
|
platforms = registry.get_available_platforms()
|
|
8
8
|
|
|
9
|
-
PrettyOutput.section("
|
|
9
|
+
PrettyOutput.section("Supported platforms and models", OutputType.SUCCESS)
|
|
10
10
|
|
|
11
11
|
for platform_name in platforms:
|
|
12
|
-
#
|
|
12
|
+
# Create platform instance
|
|
13
13
|
platform = registry.create_platform(platform_name)
|
|
14
14
|
if not platform:
|
|
15
15
|
continue
|
|
16
16
|
|
|
17
|
-
#
|
|
17
|
+
# Get the list of models supported by the platform
|
|
18
18
|
try:
|
|
19
19
|
models = platform.get_model_list()
|
|
20
20
|
|
|
21
|
-
#
|
|
21
|
+
# Print platform name
|
|
22
22
|
PrettyOutput.section(f"{platform_name}", OutputType.SUCCESS)
|
|
23
23
|
|
|
24
|
-
#
|
|
24
|
+
# Print model list
|
|
25
25
|
if models:
|
|
26
26
|
for model_name, description in models:
|
|
27
27
|
if description:
|
|
@@ -29,95 +29,95 @@ def list_platforms():
|
|
|
29
29
|
else:
|
|
30
30
|
PrettyOutput.print(f" • {model_name}", OutputType.SUCCESS)
|
|
31
31
|
else:
|
|
32
|
-
PrettyOutput.print("
|
|
32
|
+
PrettyOutput.print(" • No available model information", OutputType.WARNING)
|
|
33
33
|
|
|
34
34
|
except Exception as e:
|
|
35
|
-
PrettyOutput.print(f"
|
|
35
|
+
PrettyOutput.print(f"Failed to get model list for {platform_name}: {str(e)}", OutputType.WARNING)
|
|
36
36
|
|
|
37
37
|
def chat_with_model(platform_name: str, model_name: str):
|
|
38
|
-
"""
|
|
38
|
+
"""Chat with specified platform and model"""
|
|
39
39
|
registry = PlatformRegistry.get_global_platform_registry()
|
|
40
40
|
|
|
41
|
-
#
|
|
41
|
+
# Create platform instance
|
|
42
42
|
platform = registry.create_platform(platform_name)
|
|
43
43
|
if not platform:
|
|
44
|
-
PrettyOutput.print(f"
|
|
44
|
+
PrettyOutput.print(f"Failed to create platform {platform_name}", OutputType.ERROR)
|
|
45
45
|
return
|
|
46
46
|
|
|
47
47
|
try:
|
|
48
|
-
#
|
|
48
|
+
# Set model
|
|
49
49
|
platform.set_model_name(model_name)
|
|
50
|
-
PrettyOutput.print(f"
|
|
50
|
+
PrettyOutput.print(f"Connected to {platform_name} platform {model_name} model", OutputType.SUCCESS)
|
|
51
51
|
|
|
52
|
-
#
|
|
52
|
+
# Start conversation loop
|
|
53
53
|
while True:
|
|
54
|
-
#
|
|
54
|
+
# Get user input
|
|
55
55
|
user_input = get_multiline_input("")
|
|
56
56
|
|
|
57
|
-
#
|
|
57
|
+
# Check if input is cancelled
|
|
58
58
|
if user_input == "__interrupt__" or user_input.strip() == "/bye":
|
|
59
|
-
PrettyOutput.print("
|
|
59
|
+
PrettyOutput.print("Bye!", OutputType.SUCCESS)
|
|
60
60
|
break
|
|
61
61
|
|
|
62
|
-
#
|
|
62
|
+
# Check if input is empty
|
|
63
63
|
if not user_input.strip():
|
|
64
64
|
continue
|
|
65
65
|
|
|
66
|
-
#
|
|
66
|
+
# Check if it is a clear session command
|
|
67
67
|
if user_input.strip() == "/clear":
|
|
68
68
|
try:
|
|
69
69
|
platform.delete_chat()
|
|
70
|
-
platform.set_model_name(model_name) #
|
|
71
|
-
PrettyOutput.print("
|
|
70
|
+
platform.set_model_name(model_name) # Reinitialize session
|
|
71
|
+
PrettyOutput.print("Session cleared", OutputType.SUCCESS)
|
|
72
72
|
except Exception as e:
|
|
73
|
-
PrettyOutput.print(f"
|
|
73
|
+
PrettyOutput.print(f"Failed to clear session: {str(e)}", OutputType.ERROR)
|
|
74
74
|
continue
|
|
75
75
|
|
|
76
76
|
try:
|
|
77
|
-
#
|
|
77
|
+
# Send to model and get reply
|
|
78
78
|
response = platform.chat_until_success(user_input)
|
|
79
79
|
if not response:
|
|
80
|
-
PrettyOutput.print("
|
|
80
|
+
PrettyOutput.print("No valid reply", OutputType.WARNING)
|
|
81
81
|
|
|
82
82
|
except Exception as e:
|
|
83
|
-
PrettyOutput.print(f"
|
|
83
|
+
PrettyOutput.print(f"Failed to chat: {str(e)}", OutputType.ERROR)
|
|
84
84
|
|
|
85
85
|
except Exception as e:
|
|
86
|
-
PrettyOutput.print(f"
|
|
86
|
+
PrettyOutput.print(f"Failed to initialize conversation: {str(e)}", OutputType.ERROR)
|
|
87
87
|
finally:
|
|
88
|
-
#
|
|
88
|
+
# Clean up resources
|
|
89
89
|
try:
|
|
90
90
|
platform.delete_chat()
|
|
91
91
|
except:
|
|
92
92
|
pass
|
|
93
93
|
|
|
94
94
|
def info_command(args):
|
|
95
|
-
"""
|
|
95
|
+
"""Process info subcommand"""
|
|
96
96
|
list_platforms()
|
|
97
97
|
|
|
98
98
|
def chat_command(args):
|
|
99
|
-
"""
|
|
99
|
+
"""Process chat subcommand"""
|
|
100
100
|
if not args.platform or not args.model:
|
|
101
|
-
PrettyOutput.print("
|
|
101
|
+
PrettyOutput.print("Please specify platform and model. Use 'jarvis info' to view available platforms and models.", OutputType.ERROR)
|
|
102
102
|
return
|
|
103
103
|
chat_with_model(args.platform, args.model)
|
|
104
104
|
|
|
105
105
|
def main():
|
|
106
|
-
"""
|
|
106
|
+
"""Main function"""
|
|
107
107
|
import argparse
|
|
108
108
|
|
|
109
109
|
load_env_from_file()
|
|
110
110
|
|
|
111
111
|
parser = argparse.ArgumentParser(description='Jarvis AI Platform')
|
|
112
|
-
subparsers = parser.add_subparsers(dest='command', help='
|
|
112
|
+
subparsers = parser.add_subparsers(dest='command', help='Available subcommands')
|
|
113
113
|
|
|
114
|
-
# info
|
|
115
|
-
info_parser = subparsers.add_parser('info', help='
|
|
114
|
+
# info subcommand
|
|
115
|
+
info_parser = subparsers.add_parser('info', help='Display supported platforms and models information')
|
|
116
116
|
|
|
117
|
-
# chat
|
|
118
|
-
chat_parser = subparsers.add_parser('chat', help='
|
|
119
|
-
chat_parser.add_argument('--platform', '-p', help='
|
|
120
|
-
chat_parser.add_argument('--model', '-m', help='
|
|
117
|
+
# chat subcommand
|
|
118
|
+
chat_parser = subparsers.add_parser('chat', help='Chat with specified platform and model')
|
|
119
|
+
chat_parser.add_argument('--platform', '-p', help='Specify the platform to use')
|
|
120
|
+
chat_parser.add_argument('--model', '-m', help='Specify the model to use')
|
|
121
121
|
|
|
122
122
|
args = parser.parse_args()
|
|
123
123
|
|