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
ara_cli/classifier.py
CHANGED
|
@@ -72,3 +72,37 @@ class Classifier:
|
|
|
72
72
|
@lru_cache(maxsize=None)
|
|
73
73
|
def artefact_titles():
|
|
74
74
|
return Classifier.artefact_title.values()
|
|
75
|
+
|
|
76
|
+
# Leaf-node classifiers that cannot have children
|
|
77
|
+
_leaf_classifiers = {"task", "issue"}
|
|
78
|
+
|
|
79
|
+
# Contribution hierarchy: child -> valid parent classifiers
|
|
80
|
+
contribution_hierarchy = {
|
|
81
|
+
"businessgoal": ["vision"],
|
|
82
|
+
"capability": ["vision", "businessgoal"],
|
|
83
|
+
"keyfeature": ["vision", "businessgoal", "capability"],
|
|
84
|
+
"epic": ["vision", "businessgoal", "capability", "keyfeature"],
|
|
85
|
+
"userstory": ["vision", "businessgoal", "capability", "keyfeature", "epic"],
|
|
86
|
+
"example": ["vision", "businessgoal", "capability", "keyfeature", "epic", "userstory"],
|
|
87
|
+
"feature": ["vision", "businessgoal", "capability", "keyfeature", "epic", "userstory"],
|
|
88
|
+
"task": ["vision", "businessgoal", "capability", "keyfeature", "epic", "userstory", "feature"],
|
|
89
|
+
"issue": ["vision", "businessgoal", "capability", "keyfeature", "epic", "userstory", "feature"],
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@staticmethod
|
|
93
|
+
@lru_cache(maxsize=None)
|
|
94
|
+
def can_have_children(classifier: str) -> bool:
|
|
95
|
+
"""
|
|
96
|
+
Check if a classifier can have children artefacts.
|
|
97
|
+
Task and Issue are leaf-node classifiers and cannot have children.
|
|
98
|
+
"""
|
|
99
|
+
return classifier not in Classifier._leaf_classifiers
|
|
100
|
+
|
|
101
|
+
@staticmethod
|
|
102
|
+
@lru_cache(maxsize=None)
|
|
103
|
+
def get_valid_parent_classifiers(child_classifier: str) -> list:
|
|
104
|
+
"""
|
|
105
|
+
Get list of valid parent classifiers for a given child classifier.
|
|
106
|
+
Returns empty list if classifier has no valid parents (e.g., vision).
|
|
107
|
+
"""
|
|
108
|
+
return Classifier.contribution_hierarchy.get(child_classifier, [])
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from ara_cli.commands.command import Command
|
|
3
|
+
from ara_cli.error_handler import AraError
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class AgentRunCommand(Command):
|
|
7
|
+
def __init__(self, chat_instance, args):
|
|
8
|
+
self.chat_instance = chat_instance
|
|
9
|
+
self.args = args
|
|
10
|
+
self.parser = self._create_parser()
|
|
11
|
+
|
|
12
|
+
def _create_parser(self):
|
|
13
|
+
"""Creates and configures the argument parser."""
|
|
14
|
+
parser = argparse.ArgumentParser(
|
|
15
|
+
prog="AGENT_RUN",
|
|
16
|
+
description="Run a binary agent.",
|
|
17
|
+
add_help=False, # We handle help manually
|
|
18
|
+
)
|
|
19
|
+
parser.add_argument("agent_name", nargs="?",
|
|
20
|
+
help="The name of the agent to run.")
|
|
21
|
+
parser.add_argument("-b", "--base-dir", dest="base_dir",
|
|
22
|
+
help="Specify the base directory for the agent.")
|
|
23
|
+
parser.add_argument("-r", "--requirements", dest="requirements",
|
|
24
|
+
action="append", help="Specify a requirements file or directory.")
|
|
25
|
+
parser.add_argument("-h", "--help", action="store_true",
|
|
26
|
+
help="Show this help message.")
|
|
27
|
+
return parser
|
|
28
|
+
|
|
29
|
+
def _handle_help(self, arg_list):
|
|
30
|
+
"""Handles the --help flag for the agent command."""
|
|
31
|
+
agent_name = next(
|
|
32
|
+
(arg for arg in arg_list if not arg.startswith('-')), None)
|
|
33
|
+
|
|
34
|
+
if agent_name:
|
|
35
|
+
try:
|
|
36
|
+
self.chat_instance.agent_manager.run_agent(
|
|
37
|
+
agent_name, ["--help"])
|
|
38
|
+
except SystemExit:
|
|
39
|
+
pass # Common with argparse's --help
|
|
40
|
+
except Exception:
|
|
41
|
+
print(f"Displaying built-in help for {agent_name}:\n")
|
|
42
|
+
self.parser.print_help()
|
|
43
|
+
else:
|
|
44
|
+
self.parser.print_help()
|
|
45
|
+
return True
|
|
46
|
+
|
|
47
|
+
def _prepare_agent_args(self, parsed_args, unknown_args):
|
|
48
|
+
"""Prepares the arguments to be passed to the agent."""
|
|
49
|
+
agent_args = list(unknown_args)
|
|
50
|
+
|
|
51
|
+
if parsed_args.base_dir:
|
|
52
|
+
print(f"Using base directory: {parsed_args.base_dir}")
|
|
53
|
+
agent_args.extend(["--base-dir", parsed_args.base_dir])
|
|
54
|
+
|
|
55
|
+
if parsed_args.requirements:
|
|
56
|
+
print(f"Requirements Paths ({len(parsed_args.requirements)}):")
|
|
57
|
+
for req_path in parsed_args.requirements:
|
|
58
|
+
print(f" - {req_path}")
|
|
59
|
+
agent_args.extend(["--requirements", req_path])
|
|
60
|
+
|
|
61
|
+
# elif self.chat_instance.source_artefact_path:
|
|
62
|
+
# print(
|
|
63
|
+
# f"INFO: Automatically passing source artefact to agent: {self.chat_instance.source_artefact_path}")
|
|
64
|
+
# agent_args.insert(0, self.chat_instance.source_artefact_path)
|
|
65
|
+
# agent_args.insert(0, "-r")
|
|
66
|
+
|
|
67
|
+
return agent_args
|
|
68
|
+
|
|
69
|
+
def _run_agent(self, parsed_args, unknown_args):
|
|
70
|
+
"""Runs the agent with the prepared arguments."""
|
|
71
|
+
if not parsed_args.agent_name:
|
|
72
|
+
raise AraError("Usage: AGENT_RUN <agent_name> [args...]")
|
|
73
|
+
|
|
74
|
+
agent_name = parsed_args.agent_name
|
|
75
|
+
agent_args = self._prepare_agent_args(parsed_args, unknown_args)
|
|
76
|
+
|
|
77
|
+
self.chat_instance.agent_manager.run_agent(agent_name, agent_args)
|
|
78
|
+
|
|
79
|
+
def execute(self):
|
|
80
|
+
"""
|
|
81
|
+
Parses arguments and runs a binary agent, handling help requests and errors.
|
|
82
|
+
"""
|
|
83
|
+
try:
|
|
84
|
+
arg_list = self.args.split()
|
|
85
|
+
if "-h" in arg_list or "--help" in arg_list:
|
|
86
|
+
self._handle_help(arg_list)
|
|
87
|
+
return
|
|
88
|
+
|
|
89
|
+
parsed_args, unknown_args = self.parser.parse_known_args(arg_list)
|
|
90
|
+
self._run_agent(parsed_args, unknown_args)
|
|
91
|
+
|
|
92
|
+
except SystemExit:
|
|
93
|
+
# Argparse may exit, which is fine.
|
|
94
|
+
pass
|
|
95
|
+
except AraError as e:
|
|
96
|
+
raise e
|
|
97
|
+
except Exception as e:
|
|
98
|
+
print(f"An unexpected error occurred: {e}")
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from ara_cli.commands.command import Command
|
|
4
|
+
from ara_cli.directory_navigator import DirectoryNavigator
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class FetchAgentsCommand(Command):
|
|
8
|
+
"""Command to fetch binary agents from a remote URL.
|
|
9
|
+
|
|
10
|
+
This command downloads a binary agent from a hardcoded URL and
|
|
11
|
+
saves it to the project's ara/.araconfig/agents/ directory.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
AGENT_URL = "https://s3-public.talsen.team/so-agents/feature-creation"
|
|
15
|
+
|
|
16
|
+
def __init__(self, output=None):
|
|
17
|
+
"""Initialize the FetchAgentsCommand.
|
|
18
|
+
|
|
19
|
+
Parameters
|
|
20
|
+
----------
|
|
21
|
+
output : callable, optional
|
|
22
|
+
Output function for displaying messages. Defaults to print.
|
|
23
|
+
"""
|
|
24
|
+
self.output = output or print
|
|
25
|
+
|
|
26
|
+
def execute(self):
|
|
27
|
+
"""Execute the fetch-agents command.
|
|
28
|
+
|
|
29
|
+
Downloads a binary agent from a remote URL and saves it to the
|
|
30
|
+
project's .araconfig/agents directory.
|
|
31
|
+
"""
|
|
32
|
+
navigator = DirectoryNavigator()
|
|
33
|
+
original_directory = os.getcwd()
|
|
34
|
+
|
|
35
|
+
import requests
|
|
36
|
+
from rich.progress import (
|
|
37
|
+
BarColumn,
|
|
38
|
+
DownloadColumn,
|
|
39
|
+
Progress,
|
|
40
|
+
TextColumn,
|
|
41
|
+
TimeRemainingColumn,
|
|
42
|
+
TransferSpeedColumn,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
try:
|
|
46
|
+
# Navigate to ara directory
|
|
47
|
+
navigator.navigate_to_target()
|
|
48
|
+
|
|
49
|
+
dest_dir = self._get_project_agents_dir()
|
|
50
|
+
os.makedirs(dest_dir, exist_ok=True)
|
|
51
|
+
|
|
52
|
+
agent_name = self.AGENT_URL.split("/")[-1]
|
|
53
|
+
dest_path = os.path.join(dest_dir, agent_name)
|
|
54
|
+
|
|
55
|
+
self.output(f"Downloading agent from {self.AGENT_URL}...")
|
|
56
|
+
|
|
57
|
+
response = requests.get(self.AGENT_URL, stream=True)
|
|
58
|
+
response.raise_for_status()
|
|
59
|
+
|
|
60
|
+
total_size = int(response.headers.get("content-length", 0))
|
|
61
|
+
block_size = 1024
|
|
62
|
+
progress = Progress(
|
|
63
|
+
TextColumn("[bold blue]{task.description}", justify="right"),
|
|
64
|
+
BarColumn(bar_width=None),
|
|
65
|
+
"[progress.percentage]{task.percentage:>3.1f}%",
|
|
66
|
+
"•",
|
|
67
|
+
DownloadColumn(),
|
|
68
|
+
"•",
|
|
69
|
+
TransferSpeedColumn(),
|
|
70
|
+
"•",
|
|
71
|
+
TimeRemainingColumn(),
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
with progress:
|
|
75
|
+
task_id = progress.add_task(
|
|
76
|
+
f"Downloading {agent_name}", total=total_size
|
|
77
|
+
)
|
|
78
|
+
with open(dest_path, "wb") as f:
|
|
79
|
+
for data in response.iter_content(block_size):
|
|
80
|
+
progress.update(task_id, advance=len(data))
|
|
81
|
+
f.write(data)
|
|
82
|
+
|
|
83
|
+
if total_size != 0 and os.path.getsize(dest_path) != total_size:
|
|
84
|
+
raise Exception("ERROR, something went wrong during download")
|
|
85
|
+
|
|
86
|
+
# Make the binary executable
|
|
87
|
+
os.chmod(dest_path, 0o755)
|
|
88
|
+
|
|
89
|
+
self.output(f"Downloaded {agent_name} to ara/.araconfig/agents/")
|
|
90
|
+
self.output("Binary agents fetched successfully to ara/.araconfig/agents/")
|
|
91
|
+
|
|
92
|
+
except requests.exceptions.RequestException as e:
|
|
93
|
+
self.output(f"Error downloading agent: {e}")
|
|
94
|
+
finally:
|
|
95
|
+
# Return to original directory
|
|
96
|
+
os.chdir(original_directory)
|
|
97
|
+
|
|
98
|
+
def _get_project_agents_dir(self):
|
|
99
|
+
"""Get the path to the project agents directory.
|
|
100
|
+
|
|
101
|
+
Returns
|
|
102
|
+
-------
|
|
103
|
+
str
|
|
104
|
+
Path to ara/.araconfig/agents directory.
|
|
105
|
+
"""
|
|
106
|
+
return os.path.join(".araconfig", "agents")
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import shutil
|
|
3
|
+
from ara_cli.commands.command import Command
|
|
4
|
+
from ara_cli.ara_config import ConfigManager
|
|
5
|
+
from ara_cli.directory_navigator import DirectoryNavigator
|
|
6
|
+
|
|
7
|
+
class FetchScriptsCommand(Command):
|
|
8
|
+
def __init__(self, output=None):
|
|
9
|
+
self.output = output or print
|
|
10
|
+
self.config = ConfigManager.get_config()
|
|
11
|
+
|
|
12
|
+
def execute(self):
|
|
13
|
+
navigator = DirectoryNavigator()
|
|
14
|
+
original_directory = os.getcwd()
|
|
15
|
+
navigator.navigate_to_target()
|
|
16
|
+
os.chdir('..')
|
|
17
|
+
|
|
18
|
+
global_scripts_dir = self._get_global_scripts_dir()
|
|
19
|
+
global_scripts_config_dir = self._get_global_scripts_config_dir()
|
|
20
|
+
|
|
21
|
+
if not os.path.exists(global_scripts_dir):
|
|
22
|
+
self.output("Global scripts directory not found.")
|
|
23
|
+
os.chdir(original_directory)
|
|
24
|
+
return
|
|
25
|
+
|
|
26
|
+
if not os.path.exists(global_scripts_config_dir):
|
|
27
|
+
os.makedirs(global_scripts_config_dir)
|
|
28
|
+
|
|
29
|
+
for item in os.listdir(global_scripts_dir):
|
|
30
|
+
source = os.path.join(global_scripts_dir, item)
|
|
31
|
+
destination = os.path.join(global_scripts_config_dir, item)
|
|
32
|
+
if os.path.isfile(source):
|
|
33
|
+
shutil.copy2(source, destination)
|
|
34
|
+
self.output(f"Copied {item} to global scripts directory.")
|
|
35
|
+
|
|
36
|
+
os.chdir(original_directory)
|
|
37
|
+
|
|
38
|
+
def _get_global_scripts_dir(self):
|
|
39
|
+
base_path = os.path.dirname(os.path.dirname(__file__))
|
|
40
|
+
return os.path.join(base_path, "templates", "global-scripts")
|
|
41
|
+
|
|
42
|
+
def _get_global_scripts_config_dir(self):
|
|
43
|
+
return os.path.join(self.config.local_prompt_templates_dir, "global-scripts")
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from os.path import join
|
|
2
|
+
import os
|
|
3
|
+
import shutil
|
|
4
|
+
from ara_cli.commands.command import Command
|
|
5
|
+
from ara_cli.ara_config import ConfigManager
|
|
6
|
+
from ara_cli.template_manager import TemplatePathManager
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class FetchTemplatesCommand(Command):
|
|
10
|
+
def __init__(self, output=None):
|
|
11
|
+
self.output = output or print
|
|
12
|
+
|
|
13
|
+
def execute(self):
|
|
14
|
+
config = ConfigManager().get_config()
|
|
15
|
+
prompt_templates_dir = config.local_prompt_templates_dir
|
|
16
|
+
template_base_path = TemplatePathManager.get_template_base_path()
|
|
17
|
+
global_prompt_templates_path = join(
|
|
18
|
+
template_base_path, "prompt-modules")
|
|
19
|
+
|
|
20
|
+
subdirs = ["commands", "rules", "intentions", "blueprints"]
|
|
21
|
+
|
|
22
|
+
os.makedirs(join(prompt_templates_dir,
|
|
23
|
+
"global-prompt-modules"), exist_ok=True)
|
|
24
|
+
for subdir in subdirs:
|
|
25
|
+
target_dir = join(prompt_templates_dir,
|
|
26
|
+
"global-prompt-modules", subdir)
|
|
27
|
+
source_dir = join(global_prompt_templates_path, subdir)
|
|
28
|
+
os.makedirs(target_dir, exist_ok=True)
|
|
29
|
+
for item in os.listdir(source_dir):
|
|
30
|
+
source = join(source_dir, item)
|
|
31
|
+
target = join(target_dir, item)
|
|
32
|
+
shutil.copy2(source, target)
|
|
33
|
+
|
|
34
|
+
custom_prompt_templates_subdir = config.custom_prompt_templates_subdir
|
|
35
|
+
local_prompt_modules_dir = join(
|
|
36
|
+
prompt_templates_dir, custom_prompt_templates_subdir)
|
|
37
|
+
os.makedirs(local_prompt_modules_dir, exist_ok=True)
|
|
38
|
+
for subdir in subdirs:
|
|
39
|
+
os.makedirs(join(local_prompt_modules_dir, subdir), exist_ok=True)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from os.path import join
|
|
2
|
+
import os
|
|
3
|
+
import shutil
|
|
4
|
+
from ara_cli.commands.command import Command
|
|
5
|
+
from ara_cli.ara_config import ConfigManager
|
|
6
|
+
from ara_cli.template_manager import TemplatePathManager
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class FetchTemplatesCommand(Command):
|
|
10
|
+
def __init__(self, output=None):
|
|
11
|
+
self.output = output or print
|
|
12
|
+
|
|
13
|
+
def execute(self):
|
|
14
|
+
config = ConfigManager().get_config()
|
|
15
|
+
prompt_templates_dir = config.local_prompt_templates_dir
|
|
16
|
+
template_base_path = TemplatePathManager.get_template_base_path()
|
|
17
|
+
global_prompt_templates_path = join(
|
|
18
|
+
template_base_path, "prompt-modules")
|
|
19
|
+
|
|
20
|
+
subdirs = ["commands", "rules", "intentions", "blueprints"]
|
|
21
|
+
|
|
22
|
+
os.makedirs(join(prompt_templates_dir,
|
|
23
|
+
"global-prompt-modules"), exist_ok=True)
|
|
24
|
+
for subdir in subdirs:
|
|
25
|
+
target_dir = join(prompt_templates_dir,
|
|
26
|
+
"global-prompt-modules", subdir)
|
|
27
|
+
source_dir = join(global_prompt_templates_path, subdir)
|
|
28
|
+
os.makedirs(target_dir, exist_ok=True)
|
|
29
|
+
for item in os.listdir(source_dir):
|
|
30
|
+
source = join(source_dir, item)
|
|
31
|
+
target = join(target_dir, item)
|
|
32
|
+
shutil.copy2(source, target)
|
|
33
|
+
|
|
34
|
+
custom_prompt_templates_subdir = config.custom_prompt_templates_subdir
|
|
35
|
+
local_prompt_modules_dir = join(
|
|
36
|
+
prompt_templates_dir, custom_prompt_templates_subdir)
|
|
37
|
+
os.makedirs(local_prompt_modules_dir, exist_ok=True)
|
|
38
|
+
for subdir in subdirs:
|
|
39
|
+
os.makedirs(join(local_prompt_modules_dir, subdir), exist_ok=True)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from ara_cli.commands.command import Command
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def list_available_binary_agents(chat_instance):
|
|
6
|
+
"""Helper to list executable files in the agents directory."""
|
|
7
|
+
try:
|
|
8
|
+
base_dir = chat_instance._find_project_root()
|
|
9
|
+
if not base_dir:
|
|
10
|
+
return [] # Can't find project root
|
|
11
|
+
|
|
12
|
+
agents_dir = os.path.join(base_dir, "ara", ".araconfig", "agents")
|
|
13
|
+
if not os.path.isdir(agents_dir):
|
|
14
|
+
return []
|
|
15
|
+
|
|
16
|
+
available_agents = []
|
|
17
|
+
for f in os.listdir(agents_dir):
|
|
18
|
+
path = os.path.join(agents_dir, f)
|
|
19
|
+
if os.path.isfile(path) and os.access(path, os.X_OK):
|
|
20
|
+
available_agents.append(f)
|
|
21
|
+
return available_agents
|
|
22
|
+
except Exception:
|
|
23
|
+
return [] # Fail silently
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class ListAgentsCommand(Command):
|
|
27
|
+
def __init__(self, chat_instance):
|
|
28
|
+
self.chat_instance = chat_instance
|
|
29
|
+
|
|
30
|
+
def execute(self):
|
|
31
|
+
"""Lists all available executable binary agents."""
|
|
32
|
+
print("Searching for available agents in 'ara/.araconfig/agents/'...")
|
|
33
|
+
available_agents = list_available_binary_agents(self.chat_instance)
|
|
34
|
+
if available_agents:
|
|
35
|
+
print("\nAvailable binary agents:")
|
|
36
|
+
for agent in available_agents:
|
|
37
|
+
print(f" - {agent}")
|
|
38
|
+
else:
|
|
39
|
+
print("No executable binary agents found.")
|
ara_cli/commands/load_command.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from ara_cli.commands.command import Command
|
|
2
|
-
from ara_cli.file_loaders.
|
|
3
|
-
from ara_cli.file_loaders.binary_file_loader import BinaryFileLoader
|
|
2
|
+
from ara_cli.file_loaders.factories.file_loader_factory import FileLoaderFactory
|
|
3
|
+
from ara_cli.file_loaders.loaders.binary_file_loader import BinaryFileLoader
|
|
4
|
+
from ara_cli import BINARY_TYPE_MAPPING
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
class LoadCommand(Command):
|
|
@@ -29,7 +30,7 @@ class LoadCommand(Command):
|
|
|
29
30
|
# Determine mime type for binary files
|
|
30
31
|
file_name_lower = self.file_path.lower()
|
|
31
32
|
mime_type = None
|
|
32
|
-
for extension, mt in
|
|
33
|
+
for extension, mt in BINARY_TYPE_MAPPING.items():
|
|
33
34
|
if file_name_lower.endswith(extension):
|
|
34
35
|
mime_type = mt
|
|
35
36
|
break
|
ara_cli/commands/read_command.py
CHANGED
|
@@ -3,9 +3,9 @@ from ara_cli.artefact_reader import ArtefactReader
|
|
|
3
3
|
from ara_cli.file_classifier import FileClassifier
|
|
4
4
|
from ara_cli.list_filter import ListFilter, filter_list
|
|
5
5
|
from ara_cli.artefact_models.artefact_data_retrieval import (
|
|
6
|
-
artefact_content_retrieval,
|
|
7
|
-
artefact_path_retrieval,
|
|
8
|
-
artefact_tags_retrieval
|
|
6
|
+
artefact_content_retrieval,
|
|
7
|
+
artefact_path_retrieval,
|
|
8
|
+
artefact_tags_retrieval,
|
|
9
9
|
)
|
|
10
10
|
from ara_cli.artefact_fuzzy_search import suggest_close_name_matches
|
|
11
11
|
import os
|
|
@@ -18,7 +18,7 @@ class ReadCommand(Command):
|
|
|
18
18
|
artefact_name: str,
|
|
19
19
|
read_mode: str = "default",
|
|
20
20
|
list_filter: ListFilter = None,
|
|
21
|
-
output=None
|
|
21
|
+
output=None,
|
|
22
22
|
):
|
|
23
23
|
self.classifier = classifier
|
|
24
24
|
self.artefact_name = artefact_name
|
|
@@ -29,7 +29,8 @@ class ReadCommand(Command):
|
|
|
29
29
|
def execute(self) -> bool:
|
|
30
30
|
"""Execute the read command and return success status."""
|
|
31
31
|
file_classifier = FileClassifier(os)
|
|
32
|
-
|
|
32
|
+
reader = ArtefactReader()
|
|
33
|
+
classified_artefacts = reader.read_artefacts()
|
|
33
34
|
|
|
34
35
|
if not self.classifier or not self.artefact_name:
|
|
35
36
|
self._filter_and_print(classified_artefacts, file_classifier)
|
|
@@ -39,15 +40,12 @@ class ReadCommand(Command):
|
|
|
39
40
|
all_artefact_names = [a.title for a in artefacts]
|
|
40
41
|
|
|
41
42
|
if self.artefact_name not in all_artefact_names:
|
|
42
|
-
suggest_close_name_matches(
|
|
43
|
-
self.artefact_name,
|
|
44
|
-
all_artefact_names
|
|
45
|
-
)
|
|
43
|
+
suggest_close_name_matches(self.artefact_name, all_artefact_names)
|
|
46
44
|
return False
|
|
47
45
|
|
|
48
|
-
target_artefact = next(
|
|
49
|
-
lambda x: x.title == self.artefact_name, artefacts
|
|
50
|
-
)
|
|
46
|
+
target_artefact = next(
|
|
47
|
+
filter(lambda x: x.title == self.artefact_name, artefacts)
|
|
48
|
+
)
|
|
51
49
|
|
|
52
50
|
artefacts_by_classifier = {self.classifier: []}
|
|
53
51
|
|
|
@@ -55,16 +53,14 @@ class ReadCommand(Command):
|
|
|
55
53
|
match self.read_mode:
|
|
56
54
|
case "branch":
|
|
57
55
|
self._handle_branch_mode(
|
|
58
|
-
classified_artefacts, artefacts_by_classifier
|
|
56
|
+
classified_artefacts, artefacts_by_classifier, reader
|
|
59
57
|
)
|
|
60
58
|
case "children":
|
|
61
59
|
artefacts_by_classifier = self._handle_children_mode(
|
|
62
|
-
classified_artefacts
|
|
60
|
+
classified_artefacts, reader
|
|
63
61
|
)
|
|
64
62
|
case _:
|
|
65
|
-
self._handle_default_mode(
|
|
66
|
-
target_artefact, artefacts_by_classifier
|
|
67
|
-
)
|
|
63
|
+
self._handle_default_mode(target_artefact, artefacts_by_classifier)
|
|
68
64
|
|
|
69
65
|
# Apply filtering and print results
|
|
70
66
|
self._filter_and_print(artefacts_by_classifier, file_classifier)
|
|
@@ -78,21 +74,23 @@ class ReadCommand(Command):
|
|
|
78
74
|
self.output(f"Error reading artefact: {e}")
|
|
79
75
|
return False
|
|
80
76
|
|
|
81
|
-
def _handle_branch_mode(
|
|
77
|
+
def _handle_branch_mode(
|
|
78
|
+
self, classified_artefacts, artefacts_by_classifier, reader
|
|
79
|
+
):
|
|
82
80
|
"""Handle branch read mode."""
|
|
83
|
-
|
|
81
|
+
reader.step_through_value_chain(
|
|
84
82
|
artefact_name=self.artefact_name,
|
|
85
83
|
classifier=self.classifier,
|
|
86
84
|
artefacts_by_classifier=artefacts_by_classifier,
|
|
87
|
-
classified_artefacts=classified_artefacts
|
|
85
|
+
classified_artefacts=classified_artefacts,
|
|
88
86
|
)
|
|
89
87
|
|
|
90
|
-
def _handle_children_mode(self, classified_artefacts):
|
|
88
|
+
def _handle_children_mode(self, classified_artefacts, reader):
|
|
91
89
|
"""Handle children read mode."""
|
|
92
|
-
return
|
|
90
|
+
return reader.find_children(
|
|
93
91
|
artefact_name=self.artefact_name,
|
|
94
92
|
classifier=self.classifier,
|
|
95
|
-
classified_artefacts=classified_artefacts
|
|
93
|
+
classified_artefacts=classified_artefacts,
|
|
96
94
|
)
|
|
97
95
|
|
|
98
96
|
def _handle_default_mode(self, target_artefact, artefacts_by_classifier):
|
|
@@ -106,12 +104,10 @@ class ReadCommand(Command):
|
|
|
106
104
|
list_filter=self.list_filter,
|
|
107
105
|
content_retrieval_strategy=artefact_content_retrieval,
|
|
108
106
|
file_path_retrieval=artefact_path_retrieval,
|
|
109
|
-
tag_retrieval=artefact_tags_retrieval
|
|
107
|
+
tag_retrieval=artefact_tags_retrieval,
|
|
110
108
|
)
|
|
111
109
|
|
|
112
110
|
def _filter_and_print(self, artefacts_by_classifier, file_classifier):
|
|
113
111
|
"""Apply list filtering and print results"""
|
|
114
112
|
filtered_artefacts = self._apply_filtering(artefacts_by_classifier)
|
|
115
|
-
file_classifier.print_classified_files(
|
|
116
|
-
filtered_artefacts, print_content=True
|
|
117
|
-
)
|
|
113
|
+
file_classifier.print_classified_files(filtered_artefacts, print_content=True)
|