ara-cli 0.1.10.5__py3-none-any.whl → 0.1.14.0__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.
- ara_cli/__init__.py +51 -6
- ara_cli/__main__.py +87 -75
- ara_cli/ara_command_action.py +189 -101
- ara_cli/ara_config.py +187 -128
- ara_cli/ara_subcommands/common.py +2 -2
- ara_cli/ara_subcommands/config.py +221 -0
- ara_cli/ara_subcommands/convert.py +107 -0
- ara_cli/ara_subcommands/fetch.py +41 -0
- ara_cli/ara_subcommands/fetch_agents.py +22 -0
- ara_cli/ara_subcommands/fetch_scripts.py +19 -0
- ara_cli/ara_subcommands/fetch_templates.py +15 -10
- ara_cli/ara_subcommands/list.py +97 -23
- ara_cli/ara_subcommands/prompt.py +266 -106
- ara_cli/artefact_autofix.py +117 -64
- ara_cli/artefact_converter.py +355 -0
- ara_cli/artefact_creator.py +41 -17
- ara_cli/artefact_lister.py +3 -3
- ara_cli/artefact_models/artefact_model.py +1 -1
- ara_cli/artefact_models/artefact_templates.py +0 -9
- ara_cli/artefact_models/feature_artefact_model.py +8 -8
- ara_cli/artefact_reader.py +62 -43
- ara_cli/artefact_scan.py +39 -17
- ara_cli/chat.py +300 -71
- ara_cli/chat_agent/__init__.py +0 -0
- ara_cli/chat_agent/agent_process_manager.py +155 -0
- ara_cli/chat_script_runner/__init__.py +0 -0
- ara_cli/chat_script_runner/script_completer.py +23 -0
- ara_cli/chat_script_runner/script_finder.py +41 -0
- ara_cli/chat_script_runner/script_lister.py +36 -0
- ara_cli/chat_script_runner/script_runner.py +36 -0
- ara_cli/chat_web_search/__init__.py +0 -0
- ara_cli/chat_web_search/web_search.py +263 -0
- ara_cli/children_contribution_updater.py +737 -0
- ara_cli/classifier.py +34 -0
- ara_cli/commands/agent_run_command.py +98 -0
- ara_cli/commands/fetch_agents_command.py +106 -0
- ara_cli/commands/fetch_scripts_command.py +43 -0
- ara_cli/commands/fetch_templates_command.py +39 -0
- ara_cli/commands/fetch_templates_commands.py +39 -0
- ara_cli/commands/list_agents_command.py +39 -0
- ara_cli/commands/load_command.py +4 -3
- ara_cli/commands/load_image_command.py +1 -1
- ara_cli/commands/read_command.py +23 -27
- ara_cli/completers.py +95 -35
- ara_cli/constants.py +2 -0
- ara_cli/directory_navigator.py +37 -4
- ara_cli/error_handler.py +26 -11
- ara_cli/file_loaders/document_reader.py +0 -178
- ara_cli/file_loaders/factories/__init__.py +0 -0
- ara_cli/file_loaders/factories/document_reader_factory.py +32 -0
- ara_cli/file_loaders/factories/file_loader_factory.py +27 -0
- ara_cli/file_loaders/file_loader.py +1 -30
- ara_cli/file_loaders/loaders/__init__.py +0 -0
- ara_cli/file_loaders/{document_file_loader.py → loaders/document_file_loader.py} +1 -1
- ara_cli/file_loaders/loaders/text_file_loader.py +47 -0
- ara_cli/file_loaders/readers/__init__.py +0 -0
- ara_cli/file_loaders/readers/docx_reader.py +49 -0
- ara_cli/file_loaders/readers/excel_reader.py +27 -0
- ara_cli/file_loaders/{markdown_reader.py → readers/markdown_reader.py} +1 -1
- ara_cli/file_loaders/readers/odt_reader.py +59 -0
- ara_cli/file_loaders/readers/pdf_reader.py +54 -0
- ara_cli/file_loaders/readers/pptx_reader.py +104 -0
- ara_cli/file_loaders/tools/__init__.py +0 -0
- ara_cli/llm_utils.py +58 -0
- ara_cli/output_suppressor.py +53 -0
- ara_cli/prompt_chat.py +20 -4
- ara_cli/prompt_extractor.py +47 -32
- ara_cli/prompt_handler.py +123 -17
- ara_cli/tag_extractor.py +8 -7
- ara_cli/template_loader.py +2 -1
- ara_cli/template_manager.py +52 -21
- ara_cli/templates/global-scripts/hello_global.py +1 -0
- ara_cli/templates/prompt-modules/commands/add_scenarios_for_new_behaviour.feature_creation_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/align_feature_with_implementation_changes.interview_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/analyze_codebase_and_plan_tasks.interview_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/choose_best_parent_artefact.interview_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/create_tasks_from_artefact_content.interview_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/create_tests_for_uncovered_modules.test_generation_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/derive_features_from_video_description.feature_creation_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/describe_agent_capabilities.agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/empty.commands.md +2 -12
- ara_cli/templates/prompt-modules/commands/execute_scoped_todos_in_task.interview_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/explain_single_file_purpose.interview_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/extract_file_information_bullets.interview_agent.commands.md +1 -0
- 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/fix_failing_behave_step_definitions.interview_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/fix_failing_pytest_tests.interview_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/general_instruction_policy.commands.md +47 -0
- ara_cli/templates/prompt-modules/commands/generate_and_fix_pytest_tests.test_generation_agent.commands.md +1 -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/templates/prompt-modules/commands/suggest_next_story_child_tasks.interview_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/summarize_or_transcribe_media.interview_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/update_feature_to_match_implementation.feature_creation_agent.commands.md +1 -0
- ara_cli/templates/prompt-modules/commands/update_user_story_with_requirements.interview_agent.commands.md +1 -0
- ara_cli/version.py +1 -1
- {ara_cli-0.1.10.5.dist-info → ara_cli-0.1.14.0.dist-info}/METADATA +49 -11
- ara_cli-0.1.14.0.dist-info/RECORD +253 -0
- {ara_cli-0.1.10.5.dist-info → ara_cli-0.1.14.0.dist-info}/WHEEL +1 -1
- tests/test_ara_command_action.py +31 -19
- tests/test_ara_config.py +177 -90
- tests/test_artefact_autofix.py +170 -97
- tests/test_artefact_autofix_integration.py +495 -0
- tests/test_artefact_converter.py +312 -0
- tests/test_artefact_extraction.py +564 -0
- tests/test_artefact_lister.py +11 -8
- tests/test_chat.py +166 -130
- tests/test_chat_givens_images.py +603 -0
- tests/test_chat_script_runner.py +454 -0
- tests/test_children_contribution_updater.py +98 -0
- tests/test_document_loader_office.py +267 -0
- tests/test_llm_utils.py +164 -0
- tests/test_prompt_chat.py +343 -0
- tests/test_prompt_extractor.py +683 -0
- tests/test_prompt_handler.py +416 -214
- tests/test_setup_default_chat_prompt_mode.py +198 -0
- tests/test_tag_extractor.py +95 -49
- tests/test_web_search.py +467 -0
- ara_cli/file_loaders/document_readers.py +0 -233
- ara_cli/file_loaders/file_loaders.py +0 -123
- ara_cli/file_loaders/text_file_loader.py +0 -187
- ara_cli/templates/prompt-modules/blueprints/complete_pytest_unittest.blueprint.md +0 -27
- ara_cli/templates/prompt-modules/blueprints/pytest_unittest_prompt.blueprint.md +0 -32
- 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-0.1.10.5.dist-info/RECORD +0 -194
- /ara_cli/file_loaders/{binary_file_loader.py → loaders/binary_file_loader.py} +0 -0
- /ara_cli/file_loaders/{image_processor.py → tools/image_processor.py} +0 -0
- {ara_cli-0.1.10.5.dist-info → ara_cli-0.1.14.0.dist-info}/entry_points.txt +0 -0
- {ara_cli-0.1.10.5.dist-info → ara_cli-0.1.14.0.dist-info}/top_level.txt +0 -0
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import base64
|
|
3
|
-
from abc import ABC, abstractmethod
|
|
4
|
-
from typing import Optional
|
|
5
|
-
from ara_cli.file_loaders.markdown_reader import MarkdownReader
|
|
6
|
-
from ara_cli.file_loaders.document_readers import DocumentReaderFactory
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class FileLoader(ABC):
|
|
10
|
-
"""Abstract base class for file loaders"""
|
|
11
|
-
|
|
12
|
-
def __init__(self, chat_instance):
|
|
13
|
-
self.chat = chat_instance
|
|
14
|
-
|
|
15
|
-
@abstractmethod
|
|
16
|
-
def load(self, file_path: str, **kwargs) -> bool:
|
|
17
|
-
"""Load file with specific implementation"""
|
|
18
|
-
pass
|
|
19
|
-
|
|
20
|
-
def add_prompt_tag_if_needed(self):
|
|
21
|
-
"""Add prompt tag to chat if needed"""
|
|
22
|
-
self.chat.add_prompt_tag_if_needed(self.chat.chat_name)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class TextFileLoader(FileLoader):
|
|
26
|
-
"""Loads text files"""
|
|
27
|
-
|
|
28
|
-
def load(self, file_path: str, prefix: str = "", suffix: str = "",
|
|
29
|
-
block_delimiter: str = "", extract_images: bool = False) -> bool:
|
|
30
|
-
"""Load text file with optional markdown image extraction"""
|
|
31
|
-
|
|
32
|
-
is_md_file = file_path.lower().endswith('.md')
|
|
33
|
-
|
|
34
|
-
if is_md_file and extract_images:
|
|
35
|
-
reader = MarkdownReader(file_path)
|
|
36
|
-
file_content = reader.read(extract_images=True)
|
|
37
|
-
else:
|
|
38
|
-
with open(file_path, 'r', encoding='utf-8', errors="replace") as file:
|
|
39
|
-
file_content = file.read()
|
|
40
|
-
|
|
41
|
-
if block_delimiter:
|
|
42
|
-
file_content = f"{block_delimiter}\n{file_content}\n{block_delimiter}"
|
|
43
|
-
|
|
44
|
-
write_content = f"{prefix}{file_content}{suffix}\n"
|
|
45
|
-
|
|
46
|
-
with open(self.chat.chat_name, 'a', encoding='utf-8') as chat_file:
|
|
47
|
-
chat_file.write(write_content)
|
|
48
|
-
|
|
49
|
-
return True
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
class BinaryFileLoader(FileLoader):
|
|
53
|
-
"""Loads binary files (images)"""
|
|
54
|
-
|
|
55
|
-
def load(self, file_path: str, mime_type: str, prefix: str = "", suffix: str = "") -> bool:
|
|
56
|
-
"""Load binary file as base64"""
|
|
57
|
-
|
|
58
|
-
with open(file_path, 'rb') as file:
|
|
59
|
-
file_content = file.read()
|
|
60
|
-
|
|
61
|
-
base64_image = base64.b64encode(file_content).decode("utf-8")
|
|
62
|
-
write_content = f"{prefix}{suffix}\n"
|
|
63
|
-
|
|
64
|
-
with open(self.chat.chat_name, 'a', encoding='utf-8') as chat_file:
|
|
65
|
-
chat_file.write(write_content)
|
|
66
|
-
|
|
67
|
-
return True
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
class DocumentFileLoader(FileLoader):
|
|
71
|
-
"""Loads document files (PDF, DOCX, ODT)"""
|
|
72
|
-
|
|
73
|
-
def load(self, file_path: str, prefix: str = "", suffix: str = "",
|
|
74
|
-
block_delimiter: str = "```", extract_images: bool = False) -> bool:
|
|
75
|
-
"""Load document file with optional image extraction"""
|
|
76
|
-
|
|
77
|
-
reader = DocumentReaderFactory.create_reader(file_path)
|
|
78
|
-
|
|
79
|
-
if not reader:
|
|
80
|
-
print("Unsupported document type.")
|
|
81
|
-
return False
|
|
82
|
-
|
|
83
|
-
text_content = reader.read(extract_images=extract_images)
|
|
84
|
-
|
|
85
|
-
if block_delimiter:
|
|
86
|
-
text_content = f"{block_delimiter}\n{text_content}\n{block_delimiter}"
|
|
87
|
-
|
|
88
|
-
write_content = f"{prefix}{text_content}{suffix}\n"
|
|
89
|
-
|
|
90
|
-
with open(self.chat.chat_name, 'a', encoding='utf-8') as chat_file:
|
|
91
|
-
chat_file.write(write_content)
|
|
92
|
-
|
|
93
|
-
return True
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
class FileLoaderFactory:
|
|
97
|
-
"""Factory for creating appropriate file loaders"""
|
|
98
|
-
|
|
99
|
-
BINARY_TYPE_MAPPING = {
|
|
100
|
-
".png": "image/png",
|
|
101
|
-
".jpg": "image/jpeg",
|
|
102
|
-
".jpeg": "image/jpeg",
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
DOCUMENT_TYPE_EXTENSIONS = [".docx", ".doc", ".odt", ".pdf"]
|
|
106
|
-
|
|
107
|
-
@staticmethod
|
|
108
|
-
def create_loader(file_name: str, chat_instance) -> Optional[FileLoader]:
|
|
109
|
-
"""Create appropriate loader based on file type"""
|
|
110
|
-
|
|
111
|
-
file_name_lower = file_name.lower()
|
|
112
|
-
|
|
113
|
-
# Check if it's a binary file
|
|
114
|
-
for extension, mime_type in FileLoaderFactory.BINARY_TYPE_MAPPING.items():
|
|
115
|
-
if file_name_lower.endswith(extension):
|
|
116
|
-
return BinaryFileLoader(chat_instance)
|
|
117
|
-
|
|
118
|
-
# Check if it's a document
|
|
119
|
-
if any(file_name_lower.endswith(ext) for ext in FileLoaderFactory.DOCUMENT_TYPE_EXTENSIONS):
|
|
120
|
-
return DocumentFileLoader(chat_instance)
|
|
121
|
-
|
|
122
|
-
# Default to text file loader
|
|
123
|
-
return TextFileLoader(chat_instance)
|
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import re
|
|
3
|
-
import base64
|
|
4
|
-
import tempfile
|
|
5
|
-
from typing import Optional, Tuple
|
|
6
|
-
import requests
|
|
7
|
-
from charset_normalizer import from_path
|
|
8
|
-
from ara_cli.prompt_handler import describe_image
|
|
9
|
-
from ara_cli.file_loaders.file_loader import FileLoader
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class TextFileLoader(FileLoader):
|
|
13
|
-
"""Loads text files"""
|
|
14
|
-
def load(self, file_path: str, prefix: str = "", suffix: str = "",
|
|
15
|
-
block_delimiter: str = "", extract_images: bool = False, **kwargs) -> bool:
|
|
16
|
-
"""Load text file with optional markdown image extraction"""
|
|
17
|
-
|
|
18
|
-
is_md_file = file_path.lower().endswith('.md')
|
|
19
|
-
|
|
20
|
-
if is_md_file and extract_images:
|
|
21
|
-
reader = MarkdownReader(file_path)
|
|
22
|
-
file_content = reader.read(extract_images=True).replace('\r\n', '\n')
|
|
23
|
-
else:
|
|
24
|
-
# Use charset-normalizer to detect encoding
|
|
25
|
-
encoded_content = from_path(file_path).best()
|
|
26
|
-
if not encoded_content:
|
|
27
|
-
print(f"Failed to detect encoding for {file_path}")
|
|
28
|
-
return False
|
|
29
|
-
file_content = str(encoded_content).replace('\r\n', '\n')
|
|
30
|
-
|
|
31
|
-
if block_delimiter:
|
|
32
|
-
file_content = f"{block_delimiter}\n{file_content}\n{block_delimiter}"
|
|
33
|
-
|
|
34
|
-
write_content = f"{prefix}{file_content}{suffix}\n"
|
|
35
|
-
|
|
36
|
-
with open(self.chat.chat_name, 'a', encoding='utf-8') as chat_file:
|
|
37
|
-
chat_file.write(write_content)
|
|
38
|
-
|
|
39
|
-
return True
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
class MarkdownReader:
|
|
43
|
-
"""Handles markdown file reading with optional image extraction"""
|
|
44
|
-
|
|
45
|
-
def __init__(self, file_path: str):
|
|
46
|
-
self.file_path = file_path
|
|
47
|
-
self.base_dir = os.path.dirname(file_path)
|
|
48
|
-
self.image_processor = ImageProcessor()
|
|
49
|
-
|
|
50
|
-
def read(self, extract_images: bool = False) -> str:
|
|
51
|
-
"""Read markdown file and optionally extract/describe images"""
|
|
52
|
-
with open(self.file_path, 'r', encoding='utf-8') as file:
|
|
53
|
-
content = file.read()
|
|
54
|
-
|
|
55
|
-
if not extract_images:
|
|
56
|
-
return content
|
|
57
|
-
|
|
58
|
-
return self._process_images(content)
|
|
59
|
-
|
|
60
|
-
def _process_images(self, content: str) -> str:
|
|
61
|
-
"""Process all images in markdown content"""
|
|
62
|
-
# Pattern to match markdown images: 
|
|
63
|
-
image_pattern = re.compile(r'!\[([^\]]*)\]\(([^\)]+)\)')
|
|
64
|
-
base64_pattern = re.compile(r'data:image/([^;]+);base64,([^)]+)')
|
|
65
|
-
|
|
66
|
-
# Process each image reference
|
|
67
|
-
for match in image_pattern.finditer(content):
|
|
68
|
-
image_ref = match.group(2)
|
|
69
|
-
replacement = self._process_single_image(image_ref, base64_pattern)
|
|
70
|
-
|
|
71
|
-
if replacement:
|
|
72
|
-
content = content.replace(match.group(0), replacement, 1)
|
|
73
|
-
|
|
74
|
-
return content
|
|
75
|
-
|
|
76
|
-
def _process_single_image(self, image_ref: str, base64_pattern: re.Pattern) -> Optional[str]:
|
|
77
|
-
"""Process a single image reference"""
|
|
78
|
-
try:
|
|
79
|
-
# Try base64 first
|
|
80
|
-
result = self.image_processor.process_base64_image(
|
|
81
|
-
image_ref, base64_pattern)
|
|
82
|
-
if result:
|
|
83
|
-
return result[0]
|
|
84
|
-
|
|
85
|
-
# Try URL
|
|
86
|
-
result, error = self.image_processor.process_url_image(image_ref)
|
|
87
|
-
if result:
|
|
88
|
-
if error:
|
|
89
|
-
print(f"Warning: {error}")
|
|
90
|
-
return result
|
|
91
|
-
|
|
92
|
-
# Try local file
|
|
93
|
-
result, error = self.image_processor.process_local_image(
|
|
94
|
-
image_ref, self.base_dir)
|
|
95
|
-
if error:
|
|
96
|
-
print(f"Warning: {error}")
|
|
97
|
-
return result
|
|
98
|
-
|
|
99
|
-
except Exception as e:
|
|
100
|
-
print(f"Warning: Could not process image {image_ref}: {e}")
|
|
101
|
-
return None
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
class ImageProcessor:
|
|
105
|
-
"""Handles image processing operations"""
|
|
106
|
-
|
|
107
|
-
@staticmethod
|
|
108
|
-
def process_base64_image(
|
|
109
|
-
image_ref: str,
|
|
110
|
-
base64_pattern: re.Pattern
|
|
111
|
-
) -> Optional[Tuple[str, str]]:
|
|
112
|
-
"""Process base64 encoded image and return description"""
|
|
113
|
-
base64_match = base64_pattern.match(image_ref)
|
|
114
|
-
if not base64_match:
|
|
115
|
-
return None
|
|
116
|
-
|
|
117
|
-
image_format = base64_match.group(1)
|
|
118
|
-
base64_data = base64_match.group(2)
|
|
119
|
-
image_data = base64.b64decode(base64_data)
|
|
120
|
-
|
|
121
|
-
# Create a temporary file to send to LLM
|
|
122
|
-
with tempfile.NamedTemporaryFile(suffix=f'.{image_format}', delete=False) as tmp_file:
|
|
123
|
-
tmp_file.write(image_data)
|
|
124
|
-
tmp_file_path = tmp_file.name
|
|
125
|
-
|
|
126
|
-
try:
|
|
127
|
-
description = describe_image(tmp_file_path)
|
|
128
|
-
return f"Image: (base64 embedded {image_format} image)\n[{description}]", None
|
|
129
|
-
finally:
|
|
130
|
-
os.unlink(tmp_file_path)
|
|
131
|
-
|
|
132
|
-
@staticmethod
|
|
133
|
-
def process_url_image(image_ref: str) -> Tuple[str, Optional[str]]:
|
|
134
|
-
"""Process image from URL and return description"""
|
|
135
|
-
if not image_ref.startswith(('http://', 'https://')):
|
|
136
|
-
return "", None
|
|
137
|
-
|
|
138
|
-
try:
|
|
139
|
-
response = requests.get(image_ref, timeout=10)
|
|
140
|
-
response.raise_for_status()
|
|
141
|
-
|
|
142
|
-
# Determine file extension from content-type
|
|
143
|
-
content_type = response.headers.get('content-type', '')
|
|
144
|
-
ext = ImageProcessor._get_extension_from_content_type(
|
|
145
|
-
content_type, image_ref)
|
|
146
|
-
|
|
147
|
-
# Create temporary file
|
|
148
|
-
with tempfile.NamedTemporaryFile(suffix=ext, delete=False) as tmp_file:
|
|
149
|
-
tmp_file.write(response.content)
|
|
150
|
-
tmp_file_path = tmp_file.name
|
|
151
|
-
|
|
152
|
-
try:
|
|
153
|
-
description = describe_image(tmp_file_path)
|
|
154
|
-
return f"Image: {image_ref}\n[{description}]", None
|
|
155
|
-
finally:
|
|
156
|
-
os.unlink(tmp_file_path)
|
|
157
|
-
|
|
158
|
-
except Exception as e:
|
|
159
|
-
error_msg = f"Could not download image: {str(e)}"
|
|
160
|
-
return f"Image: {image_ref}\n[{error_msg}]", error_msg
|
|
161
|
-
|
|
162
|
-
@staticmethod
|
|
163
|
-
def process_local_image(image_ref: str, base_dir: str) -> Tuple[str, Optional[str]]:
|
|
164
|
-
"""Process local image file and return description"""
|
|
165
|
-
if os.path.isabs(image_ref):
|
|
166
|
-
local_image_path = image_ref
|
|
167
|
-
else:
|
|
168
|
-
local_image_path = os.path.join(base_dir, image_ref)
|
|
169
|
-
|
|
170
|
-
if os.path.exists(local_image_path):
|
|
171
|
-
description = describe_image(local_image_path)
|
|
172
|
-
return f"Image: {image_ref}\n[{description}]", None
|
|
173
|
-
else:
|
|
174
|
-
error_msg = f"Image file not found"
|
|
175
|
-
return f"Image: {image_ref}\n[{error_msg}]", f"Local image not found: {local_image_path}"
|
|
176
|
-
|
|
177
|
-
@staticmethod
|
|
178
|
-
def _get_extension_from_content_type(content_type: str, url: str) -> str:
|
|
179
|
-
"""Determine file extension from content type or URL"""
|
|
180
|
-
if 'image/jpeg' in content_type:
|
|
181
|
-
return '.jpg'
|
|
182
|
-
elif 'image/png' in content_type:
|
|
183
|
-
return '.png'
|
|
184
|
-
elif 'image/gif' in content_type:
|
|
185
|
-
return '.gif'
|
|
186
|
-
else:
|
|
187
|
-
return os.path.splitext(url)[1] or '.png'
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# Usage:
|
|
2
|
-
# necessary input and adaption:
|
|
3
|
-
# replace text snippets in <> with specific context
|
|
4
|
-
# ...
|
|
5
|
-
# expected output:
|
|
6
|
-
# ...
|
|
7
|
-
Do not use usage information as prompt instructions
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
Given source code
|
|
11
|
-
```python
|
|
12
|
-
<source code for context, skip irrelevant for current task>
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
Given existing unit tests
|
|
16
|
-
```python
|
|
17
|
-
<existing unit tests>
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
Given pytest is available
|
|
21
|
-
|
|
22
|
-
Modify and/or create unit tests so this is fully covered:
|
|
23
|
-
```python
|
|
24
|
-
<snippet you want to cover in the next step>
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
Give me only what is relevant to testing this snippet. Use parametrization where applicable. Split into multiple tests instead of using if-else blocks. Mock all dependencies of tested code.
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
MODE: STRICT_GENERATION
|
|
2
|
-
TASK: Produce one complete pytest file for a given Python module.
|
|
3
|
-
|
|
4
|
-
REQUIREMENTS:
|
|
5
|
-
- Output only valid Python code (no text, no markdown).
|
|
6
|
-
- Target: full behavioral + branch coverage (100%).
|
|
7
|
-
- Tests follow AAA pattern (# Arrange, # Act, # Assert).
|
|
8
|
-
- Exactly ONE assert or ONE pytest.raises() per test.
|
|
9
|
-
- Use tmp_path fixture for filesystem isolation.
|
|
10
|
-
- Include an autouse=True fixture for global patching if needed.
|
|
11
|
-
- No external I/O or network calls.
|
|
12
|
-
- All tests independent, self-contained.
|
|
13
|
-
|
|
14
|
-
STYLE:
|
|
15
|
-
- File starts with module docstring describing AAA, single assert rule, autouse fixture.
|
|
16
|
-
- Group tests with comment headers:
|
|
17
|
-
# --- Success paths --- / # --- Error paths --- / # --- Edge cases ---
|
|
18
|
-
- Function names: test_<function>_<expected_behavior>_<condition>
|
|
19
|
-
- Variables descriptive (rel, path, new_content, etc.).
|
|
20
|
-
- Use direct asserts (assert result is True, assert path.read_text() == "x").
|
|
21
|
-
- For errors:
|
|
22
|
-
with pytest.raises(ExceptionType, match=r"text"): function_call()
|
|
23
|
-
|
|
24
|
-
COVERAGE:
|
|
25
|
-
- Include success, failure, and rare edge branches (e.g., conditional exceptions).
|
|
26
|
-
- Ensure 100% of conditional branches executed.
|
|
27
|
-
|
|
28
|
-
OUTPUT:
|
|
29
|
-
- Single .py file, runnable via: pytest -v --disable-warnings --maxfail=1 --cov=<target_module>
|
|
30
|
-
- No explanations or prose, only the test code.
|
|
31
|
-
|
|
32
|
-
END
|
ara_cli/templates/prompt-modules/blueprints/task_todo_list_implement_feature_BDD_way.blueprint.md
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
### INTENTION and CONTEXT
|
|
2
|
-
My intention is to setup a todo list in my given task that helps me to implement a feature in a BDD way
|
|
3
|
-
|
|
4
|
-
Now do the following:
|
|
5
|
-
Search for a line starting with `Task: ` defined in the `### GIVENS` section. Just repeat the task_name you have found as confirmation
|
|
6
|
-
* Do not proceed if no task is defined. Return immediatly with the message: "No task defined as prompt control"
|
|
7
|
-
|
|
8
|
-
* Focus on the description in the `Description` section of the defined task. Ignore all other sections.
|
|
9
|
-
* Analyze the content of the task description section and adapt your default recipe accordingly. You can add new "[@to-do]s ...", you can delete "[@to-do]s" that are not necessary anymore according to the existing task description content
|
|
10
|
-
|
|
11
|
-
* the format and formulation of your default recipe implementing a feature in BDD style is
|
|
12
|
-
```
|
|
13
|
-
[@to-do] analyze and understand the given `user story`
|
|
14
|
-
[@to-do] generate an example contributing to the rule `rule of userstory to implement` which should be turned into a scenario or feature description
|
|
15
|
-
[@to-do] use the example and aditional relevant context `{context list}` to formulate the feature file
|
|
16
|
-
[@to-do] use the formulated feature file, relevant existing step implementations and relevant existing production code to implement the new step implementations that will fail
|
|
17
|
-
[@to-do] use the created step definitions, the relevant existing production code to modify existing code and to create new code implementing the requested behavior so that the step implementations will pass
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
* append your recipe at the end of task
|
|
21
|
-
* return the extended task in the following format
|
|
22
|
-
```artefact
|
|
23
|
-
# [ ] extract
|
|
24
|
-
# filename: ara/tasks/{task_name}.task
|
|
25
|
-
{initial task content}
|
|
26
|
-
{recipe}
|
|
27
|
-
```
|
|
28
|
-
* the extract and filename statements are only allowed once per code block
|
|
29
|
-
|
|
30
|
-
* in case you think information is missing in order to generate a suffiently precise formulation, return a warning "WARNING: information is missing to formulate the new artefacts" and then explain what kind of information you think is missing and how I could easily retrieve it
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
### COMMANDS FOR THE CORRECT CONTEXTUAL CLASSIFICATION OF ARTIFACTS
|
|
2
|
-
Your job is now:
|
|
3
|
-
* analyze the given files with respect to content and relationship
|
|
4
|
-
* analyze the new artefact with respect to content and the relationship to the given files
|
|
5
|
-
* give me a list of the top 5 artefacts to which the new artefact contributes the most
|
|
6
|
-
* the output format must be a table with the columns
|
|
7
|
-
| artefact name | contribution rating from 0 (very low) - 1 (very high) | arguments for rating | path to artefact |
|
|
8
|
-
|
|
9
|
-
* in case you think the relationship of the new artefact is to weak to any given files, return a warning "WARNING: new artefact is not directly related to already existing aretefacts" and then make a proposal with regard of the ara "work orchestration contribution hierarchy" and/or the "specification contribution hierarchy"
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
### COMMANDS FOR EXTENDING EXISTING AGILE REQUIREMENTS ARTIFACTS
|
|
2
|
-
Your job is now:
|
|
3
|
-
* analyze the given files with respect to content and relationship
|
|
4
|
-
* analyze the new or changed behavior with respect to content and the relationship to the existing artefacts
|
|
5
|
-
* Develop formulation strategies that minimize formulation changes of existing changes.
|
|
6
|
-
* generate a formulation proposal that adds the new context and or behavior for the specified documents
|
|
7
|
-
* wrap and return the formulated in the following format
|
|
8
|
-
```artefact
|
|
9
|
-
# [ ] extract
|
|
10
|
-
# filename: {path/filename.filextension}
|
|
11
|
-
{formulation}
|
|
12
|
-
```
|
|
13
|
-
* the extract and filename statements are only allowed once per code block
|
|
14
|
-
|
|
15
|
-
* Adhere strictly to established rules for AGILE PRODUCT OWNERS for high-quality specification artefacts.
|
|
16
|
-
|
|
17
|
-
* in case you think information is missing in order to generate a suffiently precise formulation, return a warning "WARNING: information is missing to formulate the new aretefacts" and then explain what kind of information you think is missing and how I could easily retrieve it
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
### COMMANDS FOR FORMULATING AGILE REQUIREMENTS ARTIFACTS
|
|
2
|
-
Your job is now:
|
|
3
|
-
* analyze the given files with respect to content and relationship
|
|
4
|
-
* analyze the new artefact with respect to content and the relationship to the given files
|
|
5
|
-
* generate a formulation proposal for the specified documents
|
|
6
|
-
* wrap and return the formulated in the following format
|
|
7
|
-
```artefact
|
|
8
|
-
# [ ] extract
|
|
9
|
-
# filename: {path/filename.filextension}
|
|
10
|
-
{formulation}
|
|
11
|
-
```
|
|
12
|
-
* the extract and filename statements are only allowed once per code block
|
|
13
|
-
|
|
14
|
-
* in case you think information is missing in order to generate a suffiently precise formulation, return a warning "WARNING: information is missing to formulate the new artefacts" and then explain what kind of information you think is missing and how I could easily retrieve it
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
### COMMANDS FOR IMPLEMENTING A STEP IMPLEMENTATION FROM A GIVEN FEATURE FILE
|
|
2
|
-
Your job is now:
|
|
3
|
-
* Silently analyze the given feature file to understand the required step implementations.
|
|
4
|
-
* Silently review any additionally provided source files to check if any reusable step implementations already exist or if the necessary support methods are available.
|
|
5
|
-
* Develop implementation strategies that minimize code changes, prefer reusing existing methods and step definitions over new implementations.
|
|
6
|
-
* Use this example of a simple feature file, the corresponding step definitions and the production code as best practice to get your job done
|
|
7
|
-
"""
|
|
8
|
-
Feature file:
|
|
9
|
-
**features/arithmetic.feature**
|
|
10
|
-
```gherkin
|
|
11
|
-
Feature: Arithmetic Operations
|
|
12
|
-
|
|
13
|
-
Contributes to: <Any artefact name to which this feature contributes value> <Classifier of this artefact>
|
|
14
|
-
|
|
15
|
-
Scenario: Addition of two numbers
|
|
16
|
-
Given the CLI is initialized
|
|
17
|
-
When the user runs the addition command with "2" and "3"
|
|
18
|
-
Then the result should be "5"
|
|
19
|
-
|
|
20
|
-
Scenario Outline: Subtraction of two numbers
|
|
21
|
-
Given the CLI is initialized
|
|
22
|
-
When the user runs the subtraction command with "<num1>" and "<num2>"
|
|
23
|
-
Then the result should be "<result>"
|
|
24
|
-
|
|
25
|
-
Examples:
|
|
26
|
-
| num1 | num2 | result |
|
|
27
|
-
| 5 | 3 | 2 |
|
|
28
|
-
| 10 | 4 | 6 |
|
|
29
|
-
| 0 | 0 | 0 |
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
Step Definitions in Python with behave as BDD test framework:
|
|
33
|
-
**features/steps/arithmetic_steps.py**
|
|
34
|
-
```python
|
|
35
|
-
import subprocess
|
|
36
|
-
from behave import given, when, then
|
|
37
|
-
|
|
38
|
-
@given('the CLI is initialized')
|
|
39
|
-
def step_given_cli_initialized(context):
|
|
40
|
-
context.cli_command = 'python path/to/your_arithmetic_script.py'
|
|
41
|
-
|
|
42
|
-
@when('the user runs the addition command with "{num1}" and "{num2}"')
|
|
43
|
-
def step_when_user_runs_addition_command(context, num1, num2):
|
|
44
|
-
context.result = subprocess.run(
|
|
45
|
-
[context.cli_command, 'add', num1, num2],
|
|
46
|
-
capture_output=True,
|
|
47
|
-
text=True
|
|
48
|
-
).stdout.strip()
|
|
49
|
-
|
|
50
|
-
@when('the user runs the subtraction command with "{num1}" and "{num2}"')
|
|
51
|
-
def step_when_user_runs_subtraction_command(context, num1, num2):
|
|
52
|
-
context.result = subprocess.run(
|
|
53
|
-
[context.cli_command, 'subtract', num1, num2],
|
|
54
|
-
capture_output=True,
|
|
55
|
-
text=True
|
|
56
|
-
).stdout.strip()
|
|
57
|
-
|
|
58
|
-
@then('the result should be "{expected_result}"')
|
|
59
|
-
def step_then_result_should_be(context, expected_result):
|
|
60
|
-
assert context.result == expected_result, f"Expected {expected_result} but got {context.result}"
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
CLI Script as example production code to satisfiy the interfaces defined in the step definitions (DO NOT GENERATE ANY PRODUCTION CODE NOW):
|
|
64
|
-
**your_arithmetic_script.py**
|
|
65
|
-
```python
|
|
66
|
-
import sys
|
|
67
|
-
|
|
68
|
-
def add(a, b):
|
|
69
|
-
return int(a) + int(b)
|
|
70
|
-
|
|
71
|
-
def subtract(a, b):
|
|
72
|
-
return int(a) - int(b)
|
|
73
|
-
|
|
74
|
-
if __name__ == "__main__":
|
|
75
|
-
if len(sys.argv) != 4:
|
|
76
|
-
print("Usage: python your_arithmetic_script.py <operation> <num1> <num2>")
|
|
77
|
-
sys.exit(1)
|
|
78
|
-
|
|
79
|
-
operation = sys.argv[1]
|
|
80
|
-
num1 = sys.argv[2]
|
|
81
|
-
num2 = sys.argv[3]
|
|
82
|
-
|
|
83
|
-
if operation == 'add':
|
|
84
|
-
print(add(num1, num2))
|
|
85
|
-
elif operation == 'subtract':
|
|
86
|
-
print(subtract(num1, num2))
|
|
87
|
-
else:
|
|
88
|
-
print(f"Unknown operation: {operation}")
|
|
89
|
-
sys.exit(1)
|
|
90
|
-
```
|
|
91
|
-
"""
|
|
92
|
-
* Systematically search and check if any of the new step definitions is already existing in any given step file. It must then be omitted in the new step definitions generation. Otherwise it will create an ambiguous steps error in the behave registry.
|
|
93
|
-
* return the generated step definitions in this format:
|
|
94
|
-
```python
|
|
95
|
-
# [ ] extract
|
|
96
|
-
# filename: {path/filename}.py
|
|
97
|
-
{python code}
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
* The extract and filename statements are only allowed once per code block.
|
|
101
|
-
* Adhere strictly to established rules for high-quality Python code and architecture.
|
|
102
|
-
* If essential information is missing for code generation, issue a warning: "WARNING: Information is missing to do a correct step implementation." Specify what information is lacking and suggest how it might be retrieved.
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
### COMMANDS FOR IMPLEMENTING THE INTENDED GOAL
|
|
2
|
-
Your job is now:
|
|
3
|
-
* Silently analyze the intended behavior and draft potential new implementations in pseudo code.
|
|
4
|
-
* Silently review the provided source files to understand both the current behavior and the intended new implementation.
|
|
5
|
-
* Develop implementation strategies that minimize code changes, prefer reusing existing methods over new implementations.
|
|
6
|
-
* Output a "change table" listing all necessary changes. Include an example line for reference:
|
|
7
|
-
| filename | method | short description of intended changes |
|
|
8
|
-
| {filename}.py | {method name of existing or new method} | {detailed explanation of the changes serving as code generation prompt} |
|
|
9
|
-
|
|
10
|
-
* Implement the changes as specified in the change table, ensuring your generated code blocks are not just code snippets but at complete method levels. Use for every single generated code block this format:
|
|
11
|
-
```python
|
|
12
|
-
# [ ] extract
|
|
13
|
-
# filename: {path/filename}.py
|
|
14
|
-
{python code}
|
|
15
|
-
```
|
|
16
|
-
* the extract and filename statements are only allowed once per code block
|
|
17
|
-
|
|
18
|
-
* Adhere strictly to established rules for high-quality Python code and architecture.
|
|
19
|
-
|
|
20
|
-
* If essential information is missing for code generation, issue a warning: "WARNING: Information is missing to do a correct implementation." Specify what information is lacking and suggest how it might be retrieved.
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
### COMMANDS FOR AN OBVIOUS IMPLEMENTATION THE INTENDED GOAL
|
|
2
|
-
Your job is now:
|
|
3
|
-
* remember you are strictly following your given RULES AS EXPERT PYTHON DEVELOPER for code and architectural code quality
|
|
4
|
-
* change only code that must changed
|
|
5
|
-
* Implement the code ensuring your generated code blocks are not just code snippets but at complete method levels. Use for every single generated code block this format:
|
|
6
|
-
```python
|
|
7
|
-
# [ ] extract
|
|
8
|
-
# filename: {path/filename}.py
|
|
9
|
-
{python code}
|
|
10
|
-
```
|
|
11
|
-
* the extract and filename statements are only allowed once per code block
|
|
12
|
-
|
|
13
|
-
* in case you think information is missing in order to generate a suffiently precise formulation, return a warning "WARNING: information is missing to formulate the new aretefacts" and then explain what kind of information you think is missing and how I could easily retrieve it
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
### COMMANDS FOR ERROR FIXING
|
|
2
|
-
Your job is now to fix the error:
|
|
3
|
-
* Silently analyze the described error and draft a potential solution to the fix the error
|
|
4
|
-
* Silently review the provided source files to understand both the current faulty implementation and the intended changes to fix the error.
|
|
5
|
-
* Develop implementation strategies that minimize code changes, prefer reusing existing methods over new implementations.
|
|
6
|
-
* Output a "change table" listing all necessary changes. Include an example line for reference:
|
|
7
|
-
| filename | method | short description of intended changes |
|
|
8
|
-
| {filename}.py | {method name of existing or new method} | {detailed explanation of the changes serving as code generation prompt} |
|
|
9
|
-
|
|
10
|
-
* Implement the changes as specified in the change table, ensuring your generated code blocks are not just code snippets but at complete method levels. Use for every single generated code block this format:
|
|
11
|
-
```python
|
|
12
|
-
# [ ] extract
|
|
13
|
-
# filename: {path/filename}.py
|
|
14
|
-
{python code}
|
|
15
|
-
```
|
|
16
|
-
* the extract and filename statements are only allowed once per code block
|
|
17
|
-
|
|
18
|
-
* Adhere strictly to established rules for high-quality Python code and architecture.
|
|
19
|
-
|
|
20
|
-
* If essential information is missing for code generation, issue a warning: "WARNING: Information is missing to do a correct implementation." Specify what information is lacking and suggest how it might be retrieved.
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
### COMMANDS FOR UPDATING THE FORMULATION OF FEATURE FILES
|
|
2
|
-
Your job is now:
|
|
3
|
-
* Examine the designated feature file, ensuring it aligns with the content and its relationships within the context files.
|
|
4
|
-
* If there is a discrepancy between the feature's specifications and the system behavior described in the context files, defer to the behavior outlined in the context files. This also applies to behaviors not yet described in the existing feature file.
|
|
5
|
-
* return a table of your five top rated proposed enhancements sorted by the "Formulation enhancement rating" and formatted in the following way (one example line is given as reference):
|
|
6
|
-
| Number | filename | Scenario name | Line of feature file (from - to) | Formulation enhancement rating (0 - 1) | explanation of enhancement |
|
|
7
|
-
| 1 | file.feature | some_scenario | 30-65 | 0.9 | {here comes an explanation and reasoning of the updated formulation and a reference to the context source} |
|
|
8
|
-
|
|
9
|
-
* Propose a revised formulation for the feature file based on the analysis.
|
|
10
|
-
* wrap and return the revised formulation in the following format
|
|
11
|
-
```artefact
|
|
12
|
-
# [ ] extract
|
|
13
|
-
# filename: {path/artefac_filename.feature}
|
|
14
|
-
{formulation}
|
|
15
|
-
```
|
|
16
|
-
* the extract and filename statements are only allowed once per code block
|
|
17
|
-
|
|
18
|
-
* in case you think information is missing in order to generate a suffiently precise formulation, return a warning "WARNING: information is missing to update the formulation of the designated feature file" and then explain what kind of information you think is missing and how I could easily retrieve it
|