ara-cli 0.1.9.69__py3-none-any.whl → 0.1.10.8__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 ara-cli might be problematic. Click here for more details.
- ara_cli/__init__.py +18 -2
- ara_cli/__main__.py +248 -62
- ara_cli/ara_command_action.py +155 -86
- ara_cli/ara_config.py +226 -80
- ara_cli/ara_subcommands/__init__.py +0 -0
- ara_cli/ara_subcommands/autofix.py +26 -0
- ara_cli/ara_subcommands/chat.py +27 -0
- ara_cli/ara_subcommands/classifier_directory.py +16 -0
- ara_cli/ara_subcommands/common.py +100 -0
- ara_cli/ara_subcommands/create.py +75 -0
- ara_cli/ara_subcommands/delete.py +22 -0
- ara_cli/ara_subcommands/extract.py +22 -0
- ara_cli/ara_subcommands/fetch_templates.py +14 -0
- ara_cli/ara_subcommands/list.py +65 -0
- ara_cli/ara_subcommands/list_tags.py +25 -0
- ara_cli/ara_subcommands/load.py +48 -0
- ara_cli/ara_subcommands/prompt.py +136 -0
- ara_cli/ara_subcommands/read.py +47 -0
- ara_cli/ara_subcommands/read_status.py +20 -0
- ara_cli/ara_subcommands/read_user.py +20 -0
- ara_cli/ara_subcommands/reconnect.py +27 -0
- ara_cli/ara_subcommands/rename.py +22 -0
- ara_cli/ara_subcommands/scan.py +14 -0
- ara_cli/ara_subcommands/set_status.py +22 -0
- ara_cli/ara_subcommands/set_user.py +22 -0
- ara_cli/ara_subcommands/template.py +16 -0
- ara_cli/artefact_autofix.py +649 -68
- ara_cli/artefact_creator.py +8 -11
- ara_cli/artefact_deleter.py +2 -4
- ara_cli/artefact_fuzzy_search.py +22 -10
- ara_cli/artefact_link_updater.py +4 -4
- ara_cli/artefact_lister.py +29 -55
- ara_cli/artefact_models/artefact_data_retrieval.py +23 -0
- ara_cli/artefact_models/artefact_load.py +11 -3
- ara_cli/artefact_models/artefact_model.py +146 -39
- ara_cli/artefact_models/artefact_templates.py +70 -44
- ara_cli/artefact_models/businessgoal_artefact_model.py +23 -25
- ara_cli/artefact_models/epic_artefact_model.py +34 -26
- ara_cli/artefact_models/feature_artefact_model.py +203 -64
- ara_cli/artefact_models/keyfeature_artefact_model.py +21 -24
- ara_cli/artefact_models/serialize_helper.py +1 -1
- ara_cli/artefact_models/task_artefact_model.py +83 -15
- ara_cli/artefact_models/userstory_artefact_model.py +37 -27
- ara_cli/artefact_models/vision_artefact_model.py +23 -42
- ara_cli/artefact_reader.py +92 -91
- ara_cli/artefact_renamer.py +8 -4
- ara_cli/artefact_scan.py +66 -3
- ara_cli/chat.py +622 -162
- ara_cli/chat_agent/__init__.py +0 -0
- ara_cli/chat_agent/agent_communicator.py +62 -0
- ara_cli/chat_agent/agent_process_manager.py +211 -0
- ara_cli/chat_agent/agent_status_manager.py +73 -0
- ara_cli/chat_agent/agent_workspace_manager.py +76 -0
- ara_cli/commands/__init__.py +0 -0
- ara_cli/commands/command.py +7 -0
- ara_cli/commands/extract_command.py +15 -0
- ara_cli/commands/load_command.py +65 -0
- ara_cli/commands/load_image_command.py +34 -0
- ara_cli/commands/read_command.py +117 -0
- ara_cli/completers.py +144 -0
- ara_cli/directory_navigator.py +37 -4
- ara_cli/error_handler.py +134 -0
- ara_cli/file_classifier.py +6 -5
- ara_cli/file_lister.py +1 -1
- ara_cli/file_loaders/__init__.py +0 -0
- ara_cli/file_loaders/binary_file_loader.py +33 -0
- ara_cli/file_loaders/document_file_loader.py +34 -0
- ara_cli/file_loaders/document_reader.py +245 -0
- ara_cli/file_loaders/document_readers.py +233 -0
- ara_cli/file_loaders/file_loader.py +50 -0
- ara_cli/file_loaders/file_loaders.py +123 -0
- ara_cli/file_loaders/image_processor.py +89 -0
- ara_cli/file_loaders/markdown_reader.py +75 -0
- ara_cli/file_loaders/text_file_loader.py +187 -0
- ara_cli/global_file_lister.py +51 -0
- ara_cli/list_filter.py +1 -1
- ara_cli/output_suppressor.py +1 -1
- ara_cli/prompt_extractor.py +215 -88
- ara_cli/prompt_handler.py +521 -134
- ara_cli/prompt_rag.py +2 -2
- ara_cli/tag_extractor.py +83 -38
- ara_cli/template_loader.py +245 -0
- ara_cli/template_manager.py +18 -13
- ara_cli/templates/prompt-modules/commands/empty.commands.md +2 -12
- ara_cli/templates/prompt-modules/commands/extract_general.commands.md +12 -0
- ara_cli/templates/prompt-modules/commands/extract_markdown.commands.md +11 -0
- ara_cli/templates/prompt-modules/commands/extract_python.commands.md +13 -0
- ara_cli/templates/prompt-modules/commands/feature_add_or_modifiy_specified_behavior.commands.md +36 -0
- ara_cli/templates/prompt-modules/commands/feature_generate_initial_specified_bevahior.commands.md +53 -0
- ara_cli/templates/prompt-modules/commands/prompt_template_tech_stack_transformer.commands.md +95 -0
- ara_cli/templates/prompt-modules/commands/python_bug_fixing_code.commands.md +34 -0
- ara_cli/templates/prompt-modules/commands/python_generate_code.commands.md +27 -0
- ara_cli/templates/prompt-modules/commands/python_refactoring_code.commands.md +39 -0
- ara_cli/templates/prompt-modules/commands/python_step_definitions_generation_and_fixing.commands.md +40 -0
- ara_cli/templates/prompt-modules/commands/python_unittest_generation_and_fixing.commands.md +48 -0
- ara_cli/update_config_prompt.py +9 -3
- ara_cli/version.py +1 -1
- ara_cli-0.1.10.8.dist-info/METADATA +241 -0
- ara_cli-0.1.10.8.dist-info/RECORD +193 -0
- tests/test_ara_command_action.py +73 -59
- tests/test_ara_config.py +341 -36
- tests/test_artefact_autofix.py +1060 -0
- tests/test_artefact_link_updater.py +3 -3
- tests/test_artefact_lister.py +52 -132
- tests/test_artefact_renamer.py +2 -2
- tests/test_artefact_scan.py +327 -33
- tests/test_chat.py +2063 -498
- tests/test_file_classifier.py +24 -1
- tests/test_file_creator.py +3 -5
- tests/test_file_lister.py +1 -1
- tests/test_global_file_lister.py +131 -0
- tests/test_list_filter.py +2 -2
- tests/test_prompt_handler.py +746 -0
- tests/test_tag_extractor.py +19 -13
- tests/test_template_loader.py +192 -0
- tests/test_template_manager.py +5 -4
- tests/test_update_config_prompt.py +2 -2
- ara_cli/ara_command_parser.py +0 -327
- ara_cli/templates/prompt-modules/blueprints/complete_pytest_unittest.blueprint.md +0 -27
- ara_cli/templates/prompt-modules/blueprints/task_todo_list_implement_feature_BDD_way.blueprint.md +0 -30
- ara_cli/templates/prompt-modules/commands/artefact_classification.commands.md +0 -9
- ara_cli/templates/prompt-modules/commands/artefact_extension.commands.md +0 -17
- ara_cli/templates/prompt-modules/commands/artefact_formulation.commands.md +0 -14
- ara_cli/templates/prompt-modules/commands/behave_step_generation.commands.md +0 -102
- ara_cli/templates/prompt-modules/commands/code_generation_complex.commands.md +0 -20
- ara_cli/templates/prompt-modules/commands/code_generation_simple.commands.md +0 -13
- ara_cli/templates/prompt-modules/commands/error_fixing.commands.md +0 -20
- ara_cli/templates/prompt-modules/commands/feature_file_update.commands.md +0 -18
- ara_cli/templates/prompt-modules/commands/feature_formulation.commands.md +0 -43
- ara_cli/templates/prompt-modules/commands/js_code_generation_simple.commands.md +0 -13
- ara_cli/templates/prompt-modules/commands/refactoring.commands.md +0 -15
- ara_cli/templates/prompt-modules/commands/refactoring_analysis.commands.md +0 -9
- ara_cli/templates/prompt-modules/commands/reverse_engineer_feature_file.commands.md +0 -15
- ara_cli/templates/prompt-modules/commands/reverse_engineer_program_flow.commands.md +0 -19
- ara_cli/templates/template.businessgoal +0 -10
- ara_cli/templates/template.capability +0 -10
- ara_cli/templates/template.epic +0 -15
- ara_cli/templates/template.example +0 -6
- ara_cli/templates/template.feature +0 -26
- ara_cli/templates/template.issue +0 -14
- ara_cli/templates/template.keyfeature +0 -15
- ara_cli/templates/template.task +0 -6
- ara_cli/templates/template.userstory +0 -17
- ara_cli/templates/template.vision +0 -14
- ara_cli-0.1.9.69.dist-info/METADATA +0 -16
- ara_cli-0.1.9.69.dist-info/RECORD +0 -158
- tests/test_ara_autofix.py +0 -219
- {ara_cli-0.1.9.69.dist-info → ara_cli-0.1.10.8.dist-info}/WHEEL +0 -0
- {ara_cli-0.1.9.69.dist-info → ara_cli-0.1.10.8.dist-info}/entry_points.txt +0 -0
- {ara_cli-0.1.9.69.dist-info → ara_cli-0.1.10.8.dist-info}/top_level.txt +0 -0
ara_cli/prompt_extractor.py
CHANGED
|
@@ -1,101 +1,207 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
import json_repair
|
|
5
|
+
from markdown_it import MarkdownIt
|
|
1
6
|
from ara_cli.prompt_handler import send_prompt, get_file_content
|
|
2
7
|
from ara_cli.classifier import Classifier
|
|
3
8
|
from ara_cli.directory_navigator import DirectoryNavigator
|
|
4
9
|
from ara_cli.artefact_models.artefact_mapping import title_prefix_to_artefact_class
|
|
5
|
-
import re
|
|
6
|
-
import json
|
|
7
|
-
import json_repair
|
|
8
|
-
import os
|
|
9
10
|
|
|
10
|
-
from markdown_it import MarkdownIt
|
|
11
11
|
|
|
12
|
+
def _find_extract_token(tokens):
|
|
13
|
+
"""Find the first token that needs to be processed."""
|
|
14
|
+
for token in tokens:
|
|
15
|
+
if token.type == 'fence' and token.content.strip().startswith("# [x] extract"):
|
|
16
|
+
return token
|
|
17
|
+
return None
|
|
12
18
|
|
|
13
|
-
def extract_code_blocks_md(markdown_text):
|
|
14
|
-
md = MarkdownIt()
|
|
15
|
-
tokens = md.parse(markdown_text)
|
|
16
|
-
code_blocks = [token.content for token in tokens if token.type == 'fence']
|
|
17
|
-
return code_blocks
|
|
18
19
|
|
|
20
|
+
def _extract_file_path(content_lines):
|
|
21
|
+
"""Extract file path from content lines."""
|
|
22
|
+
if not content_lines:
|
|
23
|
+
return None
|
|
24
|
+
file_path_search = re.search(r"# filename: (.+)", content_lines[0])
|
|
25
|
+
return file_path_search.group(1).strip() if file_path_search else None
|
|
19
26
|
|
|
20
|
-
def extract_responses(document_path, relative_to_ara_root=False):
|
|
21
|
-
print(f"Debug: Starting extraction from {document_path}")
|
|
22
|
-
block_extraction_counter = 0
|
|
23
27
|
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
def _find_artefact_class(content_lines):
|
|
29
|
+
"""Find the appropriate artefact class from content lines."""
|
|
30
|
+
for line in content_lines[:2]:
|
|
31
|
+
words = line.strip().split(' ')
|
|
32
|
+
if not words:
|
|
33
|
+
continue
|
|
34
|
+
first_word = words[0]
|
|
35
|
+
if first_word in title_prefix_to_artefact_class:
|
|
36
|
+
return title_prefix_to_artefact_class[first_word]
|
|
37
|
+
return None
|
|
26
38
|
|
|
27
|
-
cwd = os.getcwd()
|
|
28
|
-
if relative_to_ara_root:
|
|
29
|
-
from ara_cli.directory_navigator import DirectoryNavigator
|
|
30
|
-
navigator = DirectoryNavigator()
|
|
31
|
-
navigator.navigate_to_target()
|
|
32
|
-
os.chdir('..')
|
|
33
39
|
|
|
34
|
-
|
|
35
|
-
|
|
40
|
+
def _process_file_extraction(file_path, code_content, force, write):
|
|
41
|
+
"""Process file extraction logic."""
|
|
42
|
+
print(f"Filename extracted: {file_path}")
|
|
43
|
+
handle_existing_file(file_path, code_content, force, write)
|
|
36
44
|
|
|
37
|
-
for block in code_blocks_found:
|
|
38
|
-
block_lines = block.split('\n')
|
|
39
45
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
46
|
+
def _process_artefact_extraction(artefact_class, content_lines, force, write):
|
|
47
|
+
"""Process artefact extraction logic."""
|
|
48
|
+
artefact = artefact_class.deserialize('\n'.join(content_lines))
|
|
49
|
+
serialized_artefact = artefact.serialize()
|
|
50
|
+
|
|
51
|
+
original_directory = os.getcwd()
|
|
52
|
+
directory_navigator = DirectoryNavigator()
|
|
53
|
+
directory_navigator.navigate_to_target()
|
|
43
54
|
|
|
44
|
-
|
|
55
|
+
artefact_path = artefact.file_path
|
|
56
|
+
directory = os.path.dirname(artefact_path)
|
|
57
|
+
os.makedirs(directory, exist_ok=True)
|
|
58
|
+
handle_existing_file(artefact_path, serialized_artefact, force, write)
|
|
45
59
|
|
|
46
|
-
|
|
60
|
+
os.chdir(original_directory)
|
|
47
61
|
|
|
48
|
-
if file_path_search:
|
|
49
|
-
file_path = file_path_search.group(1).strip()
|
|
50
|
-
print(f"Filename extracted: {file_path}")
|
|
51
62
|
|
|
52
|
-
|
|
53
|
-
|
|
63
|
+
def _perform_extraction_for_block(source_lines, block_start, block_end, force, write):
|
|
64
|
+
"""Helper function to process a single, identified block."""
|
|
65
|
+
original_block_text = '\n'.join(source_lines[block_start:block_end + 1])
|
|
66
|
+
block_content_lines = source_lines[block_start + 1:block_end]
|
|
67
|
+
block_content = '\n'.join(block_content_lines)
|
|
54
68
|
|
|
55
|
-
|
|
56
|
-
|
|
69
|
+
block_lines = block_content.split('\n')
|
|
70
|
+
content_lines_after_extract = block_lines[1:]
|
|
57
71
|
|
|
58
|
-
|
|
59
|
-
|
|
72
|
+
file_path = _extract_file_path(content_lines_after_extract)
|
|
73
|
+
|
|
74
|
+
if file_path:
|
|
75
|
+
code_content = '\n'.join(content_lines_after_extract[1:])
|
|
76
|
+
_process_file_extraction(file_path, code_content, force, write)
|
|
77
|
+
else:
|
|
78
|
+
artefact_class = _find_artefact_class(content_lines_after_extract)
|
|
79
|
+
if artefact_class:
|
|
80
|
+
_process_artefact_extraction(artefact_class, content_lines_after_extract, force, write)
|
|
60
81
|
else:
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
82
|
+
print("No filename or valid artefact found, skipping processing for this block.")
|
|
83
|
+
return None, None
|
|
84
|
+
|
|
85
|
+
modified_block_text = original_block_text.replace("# [x] extract", "# [v] extract", 1)
|
|
86
|
+
return original_block_text, modified_block_text
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class FenceDetector:
|
|
90
|
+
"""Helper class to detect and match fence blocks."""
|
|
91
|
+
|
|
92
|
+
def __init__(self, source_lines):
|
|
93
|
+
self.source_lines = source_lines
|
|
94
|
+
|
|
95
|
+
def is_extract_fence(self, line_num):
|
|
96
|
+
"""Check if line is a fence with extract marker."""
|
|
97
|
+
line = self.source_lines[line_num]
|
|
98
|
+
stripped_line = line.strip()
|
|
99
|
+
|
|
100
|
+
is_fence = stripped_line.startswith('```') or stripped_line.startswith('~~~')
|
|
101
|
+
if not is_fence:
|
|
102
|
+
return False
|
|
103
|
+
|
|
104
|
+
if not (line_num + 1 < len(self.source_lines)):
|
|
105
|
+
return False
|
|
106
|
+
|
|
107
|
+
return self.source_lines[line_num + 1].strip().startswith("# [x] extract")
|
|
108
|
+
|
|
109
|
+
def find_matching_fence_end(self, start_line):
|
|
110
|
+
"""Find the matching end fence for a given start fence."""
|
|
111
|
+
fence_line = self.source_lines[start_line]
|
|
112
|
+
indentation = len(fence_line) - len(fence_line.lstrip())
|
|
113
|
+
stripped_fence_line = fence_line.strip()
|
|
114
|
+
fence_char = stripped_fence_line[0]
|
|
115
|
+
fence_length = len(stripped_fence_line) - len(stripped_fence_line.lstrip(fence_char))
|
|
116
|
+
|
|
117
|
+
for i in range(start_line + 1, len(self.source_lines)):
|
|
118
|
+
scan_line = self.source_lines[i]
|
|
119
|
+
stripped_scan_line = scan_line.strip()
|
|
120
|
+
|
|
121
|
+
if not stripped_scan_line or stripped_scan_line[0] != fence_char:
|
|
122
|
+
continue
|
|
123
|
+
|
|
124
|
+
if not all(c == fence_char for c in stripped_scan_line):
|
|
73
125
|
continue
|
|
74
|
-
artefact = artefact_class.deserialize('\n'.join(block_lines))
|
|
75
|
-
serialized_artefact = artefact.serialize()
|
|
76
126
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
127
|
+
candidate_indentation = len(scan_line) - len(scan_line.lstrip())
|
|
128
|
+
candidate_length = len(stripped_scan_line)
|
|
129
|
+
|
|
130
|
+
if candidate_length == fence_length and candidate_indentation == indentation:
|
|
131
|
+
return i
|
|
132
|
+
|
|
133
|
+
return -1
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _process_document_blocks(source_lines, force, write):
|
|
137
|
+
"""Process all extract blocks in the document."""
|
|
138
|
+
fence_detector = FenceDetector(source_lines)
|
|
139
|
+
replacements = []
|
|
140
|
+
line_num = 0
|
|
141
|
+
|
|
142
|
+
while line_num < len(source_lines):
|
|
143
|
+
if not fence_detector.is_extract_fence(line_num):
|
|
144
|
+
line_num += 1
|
|
145
|
+
continue
|
|
80
146
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
147
|
+
block_start_line = line_num
|
|
148
|
+
block_end_line = fence_detector.find_matching_fence_end(block_start_line)
|
|
149
|
+
|
|
150
|
+
if block_end_line != -1:
|
|
151
|
+
print(f"Block found and processed starting on line {block_start_line + 1}.")
|
|
152
|
+
original, modified = _perform_extraction_for_block(
|
|
153
|
+
source_lines, block_start_line, block_end_line, force, write
|
|
154
|
+
)
|
|
155
|
+
if original and modified:
|
|
156
|
+
replacements.append((original, modified))
|
|
157
|
+
line_num = block_end_line + 1
|
|
158
|
+
else:
|
|
159
|
+
line_num += 1
|
|
160
|
+
|
|
161
|
+
return replacements
|
|
86
162
|
|
|
87
|
-
os.chdir(original_directory)
|
|
88
163
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
164
|
+
def _apply_replacements(content, replacements):
|
|
165
|
+
"""Apply all replacements to the content."""
|
|
166
|
+
updated_content = content
|
|
167
|
+
for original, modified in replacements:
|
|
168
|
+
updated_content = updated_content.replace(original, modified, 1)
|
|
169
|
+
return updated_content
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def _setup_working_directory(relative_to_ara_root):
|
|
173
|
+
"""Setup working directory and return original cwd."""
|
|
174
|
+
cwd = os.getcwd()
|
|
175
|
+
if relative_to_ara_root:
|
|
176
|
+
navigator = DirectoryNavigator()
|
|
177
|
+
navigator.navigate_to_target()
|
|
178
|
+
os.chdir('..')
|
|
179
|
+
return cwd
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def extract_responses(document_path, relative_to_ara_root=False, force=False, write=False):
|
|
183
|
+
print(f"Starting extraction from '{document_path}'")
|
|
184
|
+
|
|
185
|
+
try:
|
|
186
|
+
with open(document_path, 'r', encoding='utf-8', errors='replace') as file:
|
|
187
|
+
content = file.read()
|
|
188
|
+
except FileNotFoundError:
|
|
189
|
+
print(f"Error: File not found at '{document_path}'. Skipping extraction.")
|
|
190
|
+
return
|
|
191
|
+
|
|
192
|
+
cwd = _setup_working_directory(relative_to_ara_root)
|
|
193
|
+
|
|
194
|
+
source_lines = content.split('\n')
|
|
195
|
+
replacements = _process_document_blocks(source_lines, force, write)
|
|
196
|
+
|
|
197
|
+
updated_content = _apply_replacements(content, replacements)
|
|
92
198
|
|
|
93
199
|
os.chdir(cwd)
|
|
94
|
-
|
|
95
|
-
with open(document_path, 'w') as file:
|
|
200
|
+
with open(document_path, 'w', encoding='utf-8') as file:
|
|
96
201
|
file.write(updated_content)
|
|
97
202
|
|
|
98
|
-
|
|
203
|
+
if replacements:
|
|
204
|
+
print(f"End of extraction. Found and processed {len(replacements)} blocks in '{os.path.basename(document_path)}'.")
|
|
99
205
|
|
|
100
206
|
|
|
101
207
|
def modify_and_save_file(response, file_path):
|
|
@@ -116,7 +222,7 @@ def modify_and_save_file(response, file_path):
|
|
|
116
222
|
print("Skipping block.")
|
|
117
223
|
return
|
|
118
224
|
|
|
119
|
-
with open(file_path, 'w', encoding='utf-8') as file:
|
|
225
|
+
with open(file_path, 'w', encoding='utf-8', errors='replace') as file:
|
|
120
226
|
file.write(response_data['content'])
|
|
121
227
|
print(f"File {file_path} updated successfully.")
|
|
122
228
|
except json.JSONDecodeError as ex:
|
|
@@ -127,14 +233,23 @@ def prompt_user_decision(prompt):
|
|
|
127
233
|
return input(prompt)
|
|
128
234
|
|
|
129
235
|
|
|
130
|
-
def
|
|
236
|
+
def determine_should_create(skip_query=False):
|
|
237
|
+
if skip_query:
|
|
238
|
+
return True
|
|
239
|
+
user_decision = prompt_user_decision("File does not exist. Create? (y/n): ")
|
|
240
|
+
if user_decision.lower() in ['y', 'yes']:
|
|
241
|
+
return True
|
|
242
|
+
return False
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def create_file_if_not_exist(filename, content, skip_query=False):
|
|
131
246
|
try:
|
|
132
247
|
if not os.path.exists(filename):
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
if user_decision.lower() in ['y', 'yes']:
|
|
248
|
+
if determine_should_create(skip_query):
|
|
136
249
|
# Ensure the directory exists
|
|
137
|
-
os.
|
|
250
|
+
dir_name = os.path.dirname(filename)
|
|
251
|
+
if dir_name:
|
|
252
|
+
os.makedirs(dir_name, exist_ok=True)
|
|
138
253
|
|
|
139
254
|
with open(filename, 'w', encoding='utf-8') as file:
|
|
140
255
|
file.write(content)
|
|
@@ -170,7 +285,7 @@ def create_prompt_for_file_modification(content_str, filename):
|
|
|
170
285
|
{{
|
|
171
286
|
"filename": "path/filename.filextension",
|
|
172
287
|
"content": "full content of the modified file in valid json format"
|
|
173
|
-
}}
|
|
288
|
+
}}
|
|
174
289
|
"""
|
|
175
290
|
|
|
176
291
|
# print(f"Debug: modification prompt created: {prompt_text}")
|
|
@@ -178,34 +293,46 @@ def create_prompt_for_file_modification(content_str, filename):
|
|
|
178
293
|
return prompt_text
|
|
179
294
|
|
|
180
295
|
|
|
181
|
-
def handle_existing_file(filename, block_content):
|
|
296
|
+
def handle_existing_file(filename, block_content, skip_query=False, write=False):
|
|
182
297
|
if not os.path.isfile(filename):
|
|
183
298
|
print(f"File {filename} does not exist, attempting to create")
|
|
184
|
-
|
|
299
|
+
# Ensure directory exists before writing
|
|
300
|
+
directory = os.path.dirname(filename)
|
|
301
|
+
if directory:
|
|
302
|
+
os.makedirs(directory, exist_ok=True)
|
|
303
|
+
create_file_if_not_exist(filename, block_content, skip_query)
|
|
304
|
+
|
|
305
|
+
elif write:
|
|
306
|
+
print(f"File {filename} exists. Overwriting without LLM merge as requested.")
|
|
307
|
+
try:
|
|
308
|
+
directory = os.path.dirname(filename)
|
|
309
|
+
if directory:
|
|
310
|
+
os.makedirs(directory, exist_ok=True)
|
|
311
|
+
with open(filename, 'w', encoding='utf-8', errors='replace') as file:
|
|
312
|
+
file.write(block_content)
|
|
313
|
+
print(f"File {filename} overwritten successfully.")
|
|
314
|
+
except OSError as e:
|
|
315
|
+
print(f"Error: {e}")
|
|
316
|
+
print(f"Failed to overwrite file {filename} due to an OS error")
|
|
185
317
|
else:
|
|
186
318
|
print(f"File {filename} exists, creating modification prompt")
|
|
187
319
|
prompt_text = create_prompt_for_file_modification(block_content, filename)
|
|
320
|
+
if prompt_text is None:
|
|
321
|
+
return
|
|
322
|
+
|
|
188
323
|
messages = [{"role": "user", "content": prompt_text}]
|
|
189
324
|
response = ""
|
|
190
325
|
|
|
191
|
-
for chunk in send_prompt(messages):
|
|
326
|
+
for chunk in send_prompt(messages, purpose='extraction'):
|
|
192
327
|
content = chunk.choices[0].delta.content
|
|
193
328
|
if content:
|
|
194
329
|
response += content
|
|
195
330
|
modify_and_save_file(response, filename)
|
|
196
331
|
|
|
197
332
|
|
|
198
|
-
def extract_and_save_prompt_results(classifier, param):
|
|
333
|
+
def extract_and_save_prompt_results(classifier, param, write=False):
|
|
199
334
|
sub_directory = Classifier.get_sub_directory(classifier)
|
|
200
335
|
prompt_log_file = f"ara/{sub_directory}/{param}.data/{classifier}.prompt_log.md"
|
|
201
336
|
print(f"Extract marked sections from: {prompt_log_file}")
|
|
202
337
|
|
|
203
|
-
extract_responses(prompt_log_file)
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
def update_markdown(original_content, block_content, filename):
|
|
207
|
-
"""
|
|
208
|
-
Update the markdown content by changing the extract block from "# [x] extract" to "# [v] extract"
|
|
209
|
-
"""
|
|
210
|
-
updated_content = original_content.replace("# [x] extract", "# [v] extract")
|
|
211
|
-
return updated_content
|
|
338
|
+
extract_responses(prompt_log_file, write=write)
|