ara-cli 0.1.9.81__tar.gz → 0.1.9.84__tar.gz
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-0.1.9.81 → ara_cli-0.1.9.84}/PKG-INFO +1 -1
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/chat.py +116 -90
- ara_cli-0.1.9.84/ara_cli/commands/load_command.py +65 -0
- ara_cli-0.1.9.84/ara_cli/commands/load_image_command.py +34 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/prompt_handler.py +55 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/version.py +1 -1
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli.egg-info/PKG-INFO +1 -1
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli.egg-info/SOURCES.txt +2 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/tests/test_chat.py +221 -151
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/MANIFEST.in +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/README.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/__init__.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/__main__.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/ara_command_action.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/ara_command_parser.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/ara_config.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_autofix.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_creator.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_deleter.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_fuzzy_search.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_link_updater.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_lister.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_models/__init__.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_models/artefact_load.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_models/artefact_mapping.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_models/artefact_model.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_models/artefact_templates.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_models/businessgoal_artefact_model.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_models/capability_artefact_model.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_models/epic_artefact_model.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_models/example_artefact_model.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_models/feature_artefact_model.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_models/issue_artefact_model.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_models/keyfeature_artefact_model.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_models/serialize_helper.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_models/task_artefact_model.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_models/userstory_artefact_model.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_models/vision_artefact_model.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_reader.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_renamer.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/artefact_scan.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/classifier.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/codefusionretriever.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/codehierachieretriever.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/commandline_completer.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/commands/__init__.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/commands/command.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/commands/extract_command.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/directory_navigator.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/file_classifier.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/file_lister.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/filename_validator.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/list_filter.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/output_suppressor.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/prompt_chat.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/prompt_extractor.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/prompt_rag.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/run_file_lister.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/tag_extractor.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/template_manager.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/agile.artefacts +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/blueprints/complete_pytest_unittest.blueprint.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/blueprints/empty.blueprint.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/blueprints/task_todo_list_C4_architecture_analysis.blueprint.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/blueprints/task_todo_list_implement_feature_BDD_way.blueprint.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/commands/architecture_C4_analysis.commands.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/commands/architecture_radon_cc_score.commands.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/commands/architecture_radon_halstead_v.commands.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/commands/architecture_radon_maintainability_score.commands.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/commands/artefact_classification.commands.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/commands/artefact_extension.commands.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/commands/artefact_formulation.commands.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/commands/behave_step_generation.commands.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/commands/code_generation_complex.commands.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/commands/code_generation_simple.commands.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/commands/empty.commands.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/commands/error_fixing.commands.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/commands/feature_file_update.commands.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/commands/feature_formulation.commands.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/commands/js_code_generation_simple.commands.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/commands/refactoring.commands.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/commands/refactoring_analysis.commands.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/commands/reverse_engineer_feature_file.commands.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/commands/reverse_engineer_program_flow.commands.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/intentions/classify_task.intention.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/intentions/empty.intention.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/intentions/error_fixing.intention.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/intentions/feature_fix_steps_for_scenario.intention.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/intentions/feature_formulation.intention.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/intentions/feature_reverse_formulation_from_code.intention.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/intentions/feature_scenario_implementation.intention.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/intentions/feature_scenario_implementation_update.intention.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/intentions/feature_scenario_outline_extension.intention.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/intentions/feature_update_formulation.intention.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/intentions/fibonacci_example_implementation.intention.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/intentions/js_implementation_from_task_description.intention.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/intentions/js_steps_implementation.intention.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/intentions/python_cli_implementation_with_test.intention.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/intentions/python_code_understanding.intention.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/intentions/task_implementation.intention.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/intentions/task_prompt_control_by_status.intention.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/intentions/task_stepwise_implementation_by_number.intention.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/intentions/task_stepwise_implementation_by_status.intention.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/rules/architecture_analyst.rules.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/rules/code_analyst.rules.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/rules/empty.rules.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/rules/error_analyst.rules.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/rules/gherkin_expert.rules.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/rules/js_expert_developer.rules.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/rules/product_owner.rules.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/rules/python_behave.rules.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/prompt-modules/rules/python_developer.rules.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/specification_breakdown_files/template.concept.exploration.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/specification_breakdown_files/template.concept.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/specification_breakdown_files/template.customer.exploration.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/specification_breakdown_files/template.customer.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/specification_breakdown_files/template.persona.exploration.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/specification_breakdown_files/template.persona.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/specification_breakdown_files/template.step.exploration.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/specification_breakdown_files/template.step.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/specification_breakdown_files/template.technology.exploration.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/specification_breakdown_files/template.technology.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/template.businessgoal.prompt_log.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/template.capability.prompt_log.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/template.epic.prompt_log.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/template.example.prompt_log.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/template.feature.prompt_log.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/template.issue.prompt_log.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/template.keyfeature.prompt_log.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/template.steps.prompt_log.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/template.task.prompt_log.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/template.userstory.prompt_log.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/templates/template.vision.prompt_log.md +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli/update_config_prompt.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli.egg-info/dependency_links.txt +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli.egg-info/entry_points.txt +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli.egg-info/requires.txt +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/ara_cli.egg-info/top_level.txt +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/docker/base/requirements.txt +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/setup.cfg +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/setup.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/tests/__init__.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/tests/test_ara_command_action.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/tests/test_ara_config.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/tests/test_artefact_autofix.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/tests/test_artefact_fuzzy_search.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/tests/test_artefact_link_updater.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/tests/test_artefact_lister.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/tests/test_artefact_reader.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/tests/test_artefact_renamer.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/tests/test_artefact_scan.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/tests/test_classifier.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/tests/test_directory_navigator.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/tests/test_file_classifier.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/tests/test_file_creator.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/tests/test_file_lister.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/tests/test_list_filter.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/tests/test_tag_extractor.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/tests/test_template_manager.py +0 -0
- {ara_cli-0.1.9.81 → ara_cli-0.1.9.84}/tests/test_update_config_prompt.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ara_cli
|
|
3
|
-
Version: 0.1.9.
|
|
3
|
+
Version: 0.1.9.84
|
|
4
4
|
Summary: Powerful, open source command-line tool for managing, structuring and automating software development artifacts in line with Business-Driven Development (BDD) and AI-assisted processes
|
|
5
5
|
Description-Content-Type: text/markdown
|
|
6
6
|
Requires-Dist: litellm
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import os
|
|
2
|
-
import cmd2
|
|
3
2
|
import argparse
|
|
3
|
+
import cmd2
|
|
4
4
|
from ara_cli.prompt_handler import send_prompt
|
|
5
5
|
|
|
6
|
+
from ara_cli.file_loaders.document_file_loader import DocumentFileLoader
|
|
7
|
+
from ara_cli.file_loaders.binary_file_loader import BinaryFileLoader
|
|
8
|
+
from ara_cli.file_loaders.text_file_loader import TextFileLoader
|
|
9
|
+
|
|
6
10
|
|
|
7
11
|
extract_parser = argparse.ArgumentParser()
|
|
8
12
|
extract_parser.add_argument('-s', '--skip-queries', action='store_true', help='Force extraction')
|
|
9
13
|
|
|
14
|
+
load_parser = argparse.ArgumentParser()
|
|
15
|
+
load_parser.add_argument('file_name', nargs='?', default='', help='File to load')
|
|
16
|
+
load_parser.add_argument('--load-images', action='store_true', help='Extract and describe images from documents')
|
|
17
|
+
|
|
10
18
|
|
|
11
19
|
class Chat(cmd2.Cmd):
|
|
12
20
|
CATEGORY_CHAT_CONTROL = "Chat control commands"
|
|
@@ -353,75 +361,67 @@ Start chatting (type 'HELP'/'h' for available commands, 'QUIT'/'q' to exit chat
|
|
|
353
361
|
return None
|
|
354
362
|
return file_path
|
|
355
363
|
|
|
356
|
-
@file_exists_check
|
|
357
|
-
def load_text_file(
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
364
|
+
# @file_exists_check
|
|
365
|
+
def load_text_file(
|
|
366
|
+
self,
|
|
367
|
+
file_path,
|
|
368
|
+
prefix: str = "",
|
|
369
|
+
suffix: str = "",
|
|
370
|
+
block_delimiter: str = "",
|
|
371
|
+
extract_images: bool = False
|
|
372
|
+
):
|
|
373
|
+
loader = TextFileLoader(self)
|
|
374
|
+
return loader.load(
|
|
375
|
+
file_path,
|
|
376
|
+
prefix=prefix,
|
|
377
|
+
suffix=suffix,
|
|
378
|
+
block_delimiter=block_delimiter,
|
|
379
|
+
extract_images=extract_images
|
|
380
|
+
)
|
|
367
381
|
|
|
368
|
-
@file_exists_check
|
|
382
|
+
# @file_exists_check
|
|
369
383
|
def load_binary_file(self, file_path, mime_type: str, prefix: str = "", suffix: str = ""):
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
with open(self.chat_name, 'a', encoding='utf-8') as chat_file:
|
|
379
|
-
chat_file.write(write_content)
|
|
380
|
-
return True
|
|
381
|
-
|
|
382
|
-
def read_docx(self, file_path):
|
|
383
|
-
import docx
|
|
384
|
-
doc = docx.Document(file_path)
|
|
385
|
-
return '\n'.join(para.text for para in doc.paragraphs)
|
|
386
|
-
|
|
387
|
-
def read_pdf(self, file_path):
|
|
388
|
-
import pymupdf4llm
|
|
389
|
-
return pymupdf4llm.to_markdown(file_path, write_images=False)
|
|
390
|
-
|
|
391
|
-
def read_odt(self, file_path):
|
|
392
|
-
import pymupdf4llm
|
|
393
|
-
return pymupdf4llm.to_markdown(file_path, write_images=False)
|
|
394
|
-
|
|
395
|
-
@file_exists_check
|
|
396
|
-
def load_document_file(self, file_path: str, prefix: str = "", suffix: str = "", block_delimiter: str = "```"):
|
|
397
|
-
import os
|
|
398
|
-
|
|
399
|
-
_, ext = os.path.splitext(file_path)
|
|
400
|
-
ext = ext.lower()
|
|
401
|
-
|
|
402
|
-
text_content = ""
|
|
403
|
-
match ext:
|
|
404
|
-
case ".docx":
|
|
405
|
-
text_content = self.read_docx(file_path)
|
|
406
|
-
case ".pdf":
|
|
407
|
-
text_content = self.read_pdf(file_path)
|
|
408
|
-
case ".odt":
|
|
409
|
-
text_content = self.read_odt(file_path)
|
|
410
|
-
# Add more cases if needed.
|
|
411
|
-
case _:
|
|
412
|
-
print("Unsupported document type.")
|
|
413
|
-
return False
|
|
384
|
+
loader = BinaryFileLoader(self)
|
|
385
|
+
return loader.load(
|
|
386
|
+
file_path,
|
|
387
|
+
mime_type=mime_type,
|
|
388
|
+
prefix=prefix,
|
|
389
|
+
suffix=suffix
|
|
390
|
+
)
|
|
414
391
|
|
|
415
|
-
|
|
416
|
-
|
|
392
|
+
def read_markdown(self, file_path: str, extract_images: bool = False) -> str:
|
|
393
|
+
"""Read markdown file and optionally extract/describe images"""
|
|
394
|
+
from ara_cli.file_loaders.text_file_loader import MarkdownReader
|
|
417
395
|
|
|
418
|
-
|
|
396
|
+
reader = MarkdownReader(file_path)
|
|
397
|
+
return reader.read(extract_images=extract_images)
|
|
419
398
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
399
|
+
# @file_exists_check
|
|
400
|
+
def load_document_file(
|
|
401
|
+
self,
|
|
402
|
+
file_path: str,
|
|
403
|
+
prefix: str = "",
|
|
404
|
+
suffix: str = "",
|
|
405
|
+
block_delimiter: str = "```",
|
|
406
|
+
extract_images: bool = False
|
|
407
|
+
):
|
|
408
|
+
loader = DocumentFileLoader(self)
|
|
409
|
+
return loader.load(
|
|
410
|
+
file_path,
|
|
411
|
+
prefix=prefix,
|
|
412
|
+
suffix=suffix,
|
|
413
|
+
block_delimiter=block_delimiter,
|
|
414
|
+
extract_images=extract_images
|
|
415
|
+
)
|
|
423
416
|
|
|
424
|
-
def load_file(
|
|
417
|
+
def load_file(
|
|
418
|
+
self,
|
|
419
|
+
file_name: str,
|
|
420
|
+
prefix: str = "",
|
|
421
|
+
suffix: str = "",
|
|
422
|
+
block_delimiter: str = "",
|
|
423
|
+
extract_images: bool = False
|
|
424
|
+
):
|
|
425
425
|
binary_type_mapping = Chat.BINARY_TYPE_MAPPING
|
|
426
426
|
document_type_extensions = Chat.DOCUMENT_TYPE_EXTENSIONS
|
|
427
427
|
|
|
@@ -432,28 +432,31 @@ Start chatting (type 'HELP'/'h' for available commands, 'QUIT'/'q' to exit chat
|
|
|
432
432
|
file_type = mime_type
|
|
433
433
|
break
|
|
434
434
|
|
|
435
|
-
is_file_document = any(file_name_lower.endswith(ext)
|
|
435
|
+
is_file_document = any(file_name_lower.endswith(ext)
|
|
436
|
+
for ext in document_type_extensions)
|
|
436
437
|
|
|
437
438
|
if is_file_document:
|
|
438
439
|
return self.load_document_file(
|
|
439
|
-
|
|
440
|
+
file_path=file_name,
|
|
440
441
|
prefix=prefix,
|
|
441
442
|
suffix=suffix,
|
|
442
|
-
block_delimiter=block_delimiter
|
|
443
|
+
block_delimiter=block_delimiter,
|
|
444
|
+
extract_images=extract_images
|
|
443
445
|
)
|
|
444
446
|
elif file_type:
|
|
445
447
|
return self.load_binary_file(
|
|
446
|
-
|
|
448
|
+
file_path=file_name,
|
|
447
449
|
mime_type=file_type,
|
|
448
450
|
prefix=prefix,
|
|
449
451
|
suffix=suffix
|
|
450
452
|
)
|
|
451
453
|
else:
|
|
452
454
|
return self.load_text_file(
|
|
453
|
-
|
|
455
|
+
file_path=file_name,
|
|
454
456
|
prefix=prefix,
|
|
455
457
|
suffix=suffix,
|
|
456
|
-
block_delimiter=block_delimiter
|
|
458
|
+
block_delimiter=block_delimiter,
|
|
459
|
+
extract_images=extract_images
|
|
457
460
|
)
|
|
458
461
|
|
|
459
462
|
def choose_file_to_load(self, files: list[str], pattern: str):
|
|
@@ -496,8 +499,14 @@ Start chatting (type 'HELP'/'h' for available commands, 'QUIT'/'q' to exit chat
|
|
|
496
499
|
self.message_buffer.append(self.full_input)
|
|
497
500
|
|
|
498
501
|
@cmd2.with_category(CATEGORY_CHAT_CONTROL)
|
|
499
|
-
|
|
500
|
-
|
|
502
|
+
@cmd2.with_argparser(load_parser)
|
|
503
|
+
def do_LOAD(self, args):
|
|
504
|
+
"""Load a file and append its contents to chat file. Can be given the file name in-line. Will attempt to find the file relative to chat file first, then treat the given path as absolute. Use --load-images flag to extract and describe images from documents."""
|
|
505
|
+
from ara_cli.commands.load_command import LoadCommand
|
|
506
|
+
|
|
507
|
+
file_name = args.file_name
|
|
508
|
+
load_images = args.load_images
|
|
509
|
+
|
|
501
510
|
matching_files = self.find_matching_files_to_load(file_name)
|
|
502
511
|
if not matching_files:
|
|
503
512
|
return
|
|
@@ -506,12 +515,20 @@ Start chatting (type 'HELP'/'h' for available commands, 'QUIT'/'q' to exit chat
|
|
|
506
515
|
block_delimiter = "```"
|
|
507
516
|
prefix = f"\nFile: {file_path}\n"
|
|
508
517
|
self.add_prompt_tag_if_needed(self.chat_name)
|
|
509
|
-
|
|
510
|
-
|
|
518
|
+
|
|
519
|
+
if not os.path.isdir(file_path):
|
|
520
|
+
command = LoadCommand(
|
|
521
|
+
chat_instance=self,
|
|
522
|
+
file_path=file_path,
|
|
523
|
+
prefix=prefix,
|
|
524
|
+
block_delimiter=block_delimiter,
|
|
525
|
+
extract_images=load_images,
|
|
526
|
+
output=self.poutput
|
|
527
|
+
)
|
|
528
|
+
command.execute()
|
|
511
529
|
|
|
512
530
|
def complete_LOAD(self, text, line, begidx, endidx):
|
|
513
531
|
import glob
|
|
514
|
-
|
|
515
532
|
return [x for x in glob.glob(text + '*')]
|
|
516
533
|
|
|
517
534
|
def _retrieve_ara_config(self):
|
|
@@ -547,7 +564,7 @@ Start chatting (type 'HELP'/'h' for available commands, 'QUIT'/'q' to exit chat
|
|
|
547
564
|
|
|
548
565
|
if file_type:
|
|
549
566
|
return self.load_binary_file(
|
|
550
|
-
|
|
567
|
+
file_path=file_name,
|
|
551
568
|
mime_type=file_type,
|
|
552
569
|
prefix=prefix,
|
|
553
570
|
suffix=suffix
|
|
@@ -562,22 +579,12 @@ Start chatting (type 'HELP'/'h' for available commands, 'QUIT'/'q' to exit chat
|
|
|
562
579
|
return False
|
|
563
580
|
return True
|
|
564
581
|
|
|
565
|
-
@cmd2.with_category(CATEGORY_CHAT_CONTROL)
|
|
566
|
-
def do_LOAD_DOCUMENT(self, file_name):
|
|
567
|
-
"""Load a document file (PDF, DOCX, DOC, ODT) and append its text content to chat file. Can be given the file name in-line. Will attempt to find the file relative to chat file first, then treat the given path as absolute"""
|
|
568
|
-
matching_files = self.find_matching_files_to_load(file_name)
|
|
569
|
-
if not matching_files:
|
|
570
|
-
return
|
|
571
|
-
|
|
572
|
-
for file_path in matching_files:
|
|
573
|
-
prefix = f"\nFile: {file_path}\n"
|
|
574
|
-
self.add_prompt_tag_if_needed(self.chat_name)
|
|
575
|
-
if not os.path.isdir(file_path) and self.load_document_file(file_path, prefix=prefix):
|
|
576
|
-
print(f"Loaded document file {file_path}")
|
|
577
582
|
|
|
578
583
|
@cmd2.with_category(CATEGORY_CHAT_CONTROL)
|
|
579
584
|
def do_LOAD_IMAGE(self, file_name):
|
|
580
585
|
"""Load an image file and append it to chat file. Can be given the file name in-line. Will attempt to find the file relative to chat file first, then treat the given path as absolute"""
|
|
586
|
+
from ara_cli.commands.load_image_command import LoadImageCommand
|
|
587
|
+
|
|
581
588
|
matching_files = self.find_matching_files_to_load(file_name)
|
|
582
589
|
if not matching_files:
|
|
583
590
|
return
|
|
@@ -585,8 +592,27 @@ Start chatting (type 'HELP'/'h' for available commands, 'QUIT'/'q' to exit chat
|
|
|
585
592
|
for file_path in matching_files:
|
|
586
593
|
prefix = f"\nFile: {file_path}\n"
|
|
587
594
|
self.add_prompt_tag_if_needed(self.chat_name)
|
|
588
|
-
|
|
589
|
-
|
|
595
|
+
|
|
596
|
+
if not os.path.isdir(file_path):
|
|
597
|
+
# Determine mime type
|
|
598
|
+
file_type = None
|
|
599
|
+
file_path_lower = file_path.lower()
|
|
600
|
+
for extension, mime_type in Chat.BINARY_TYPE_MAPPING.items():
|
|
601
|
+
if file_path_lower.endswith(extension):
|
|
602
|
+
file_type = mime_type
|
|
603
|
+
break
|
|
604
|
+
|
|
605
|
+
if file_type:
|
|
606
|
+
command = LoadImageCommand(
|
|
607
|
+
chat_instance=self,
|
|
608
|
+
file_path=file_path,
|
|
609
|
+
mime_type=file_type,
|
|
610
|
+
prefix=prefix,
|
|
611
|
+
output=self.poutput
|
|
612
|
+
)
|
|
613
|
+
command.execute()
|
|
614
|
+
else:
|
|
615
|
+
self.perror(f"File {file_path} not recognized as image, could not load")
|
|
590
616
|
|
|
591
617
|
@cmd2.with_category(CATEGORY_LLM_CONTROL)
|
|
592
618
|
def do_LIST_MODELS(self, _):
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from ara_cli.commands.command import Command
|
|
2
|
+
from ara_cli.file_loaders.file_loader import FileLoaderFactory
|
|
3
|
+
from ara_cli.file_loaders.binary_file_loader import BinaryFileLoader
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class LoadCommand(Command):
|
|
7
|
+
def __init__(
|
|
8
|
+
self,
|
|
9
|
+
chat_instance,
|
|
10
|
+
file_path: str,
|
|
11
|
+
prefix: str = "",
|
|
12
|
+
suffix: str = "",
|
|
13
|
+
block_delimiter: str = "",
|
|
14
|
+
extract_images: bool = False,
|
|
15
|
+
output=None
|
|
16
|
+
):
|
|
17
|
+
self.chat = chat_instance
|
|
18
|
+
self.file_path = file_path
|
|
19
|
+
self.prefix = prefix
|
|
20
|
+
self.suffix = suffix
|
|
21
|
+
self.block_delimiter = block_delimiter
|
|
22
|
+
self.extract_images = extract_images
|
|
23
|
+
self.output = output or print
|
|
24
|
+
|
|
25
|
+
def execute(self) -> bool:
|
|
26
|
+
loader = FileLoaderFactory.create_loader(self.file_path, self.chat)
|
|
27
|
+
|
|
28
|
+
if isinstance(loader, BinaryFileLoader):
|
|
29
|
+
# Determine mime type for binary files
|
|
30
|
+
file_name_lower = self.file_path.lower()
|
|
31
|
+
mime_type = None
|
|
32
|
+
for extension, mt in FileLoaderFactory.BINARY_TYPE_MAPPING.items():
|
|
33
|
+
if file_name_lower.endswith(extension):
|
|
34
|
+
mime_type = mt
|
|
35
|
+
break
|
|
36
|
+
|
|
37
|
+
if not mime_type:
|
|
38
|
+
self.output(
|
|
39
|
+
f"Could not determine mime type for {self.file_path}")
|
|
40
|
+
return False
|
|
41
|
+
|
|
42
|
+
success = loader.load(
|
|
43
|
+
self.file_path,
|
|
44
|
+
mime_type=mime_type,
|
|
45
|
+
prefix=self.prefix,
|
|
46
|
+
suffix=self.suffix
|
|
47
|
+
)
|
|
48
|
+
elif hasattr(loader, 'load'):
|
|
49
|
+
success = loader.load(
|
|
50
|
+
self.file_path,
|
|
51
|
+
prefix=self.prefix,
|
|
52
|
+
suffix=self.suffix,
|
|
53
|
+
block_delimiter=self.block_delimiter,
|
|
54
|
+
extract_images=self.extract_images
|
|
55
|
+
)
|
|
56
|
+
else:
|
|
57
|
+
return False
|
|
58
|
+
|
|
59
|
+
if success:
|
|
60
|
+
if self.extract_images and not isinstance(loader, BinaryFileLoader):
|
|
61
|
+
self.output(
|
|
62
|
+
f"Loaded contents of file {self.file_path} with images extracted")
|
|
63
|
+
else:
|
|
64
|
+
self.output(f"Loaded contents of file {self.file_path}")
|
|
65
|
+
return success
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from ara_cli.commands.command import Command
|
|
2
|
+
from ara_cli.file_loaders.binary_file_loader import BinaryFileLoader
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class LoadImageCommand(Command):
|
|
6
|
+
def __init__(
|
|
7
|
+
self,
|
|
8
|
+
chat_instance,
|
|
9
|
+
file_path: str,
|
|
10
|
+
mime_type: str,
|
|
11
|
+
prefix: str = "",
|
|
12
|
+
suffix: str = "",
|
|
13
|
+
output=None
|
|
14
|
+
):
|
|
15
|
+
self.chat = chat_instance
|
|
16
|
+
self.file_path = file_path
|
|
17
|
+
self.mime_type = mime_type
|
|
18
|
+
self.prefix = prefix
|
|
19
|
+
self.suffix = suffix
|
|
20
|
+
self.output = output or print
|
|
21
|
+
|
|
22
|
+
def execute(self) -> bool:
|
|
23
|
+
loader = BinaryFileLoader(self.chat)
|
|
24
|
+
success = loader.load(
|
|
25
|
+
self.file_path,
|
|
26
|
+
mime_type=self.mime_type,
|
|
27
|
+
prefix=self.prefix,
|
|
28
|
+
suffix=self.suffix
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
if success:
|
|
32
|
+
self.output(f"Loaded image file {self.file_path}")
|
|
33
|
+
|
|
34
|
+
return success
|
|
@@ -15,6 +15,8 @@ import glob
|
|
|
15
15
|
import logging
|
|
16
16
|
|
|
17
17
|
|
|
18
|
+
|
|
19
|
+
|
|
18
20
|
class LLMSingleton:
|
|
19
21
|
_instance = None
|
|
20
22
|
_model = None
|
|
@@ -105,6 +107,59 @@ def send_prompt(prompt):
|
|
|
105
107
|
yield chunk
|
|
106
108
|
|
|
107
109
|
|
|
110
|
+
def describe_image(image_path: str) -> str:
|
|
111
|
+
"""
|
|
112
|
+
Send an image to the LLM and get a text description.
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
image_path: Path to the image file
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
Text description of the image
|
|
119
|
+
"""
|
|
120
|
+
import base64
|
|
121
|
+
|
|
122
|
+
# Read and encode the image
|
|
123
|
+
with open(image_path, 'rb') as image_file:
|
|
124
|
+
base64_image = base64.b64encode(image_file.read()).decode('utf-8')
|
|
125
|
+
|
|
126
|
+
# Determine image type
|
|
127
|
+
image_extension = os.path.splitext(image_path)[1].lower()
|
|
128
|
+
mime_type = {
|
|
129
|
+
'.png': 'image/png',
|
|
130
|
+
'.jpg': 'image/jpeg',
|
|
131
|
+
'.jpeg': 'image/jpeg',
|
|
132
|
+
'.gif': 'image/gif',
|
|
133
|
+
'.bmp': 'image/bmp'
|
|
134
|
+
}.get(image_extension, 'image/png')
|
|
135
|
+
|
|
136
|
+
# Create message with image
|
|
137
|
+
message = {
|
|
138
|
+
"role": "user",
|
|
139
|
+
"content": [
|
|
140
|
+
{
|
|
141
|
+
"type": "text",
|
|
142
|
+
"text": "Please describe this image in detail. If it contains text, transcribe it exactly. If it's a diagram or chart, explain its structure and content. If it's a photo or illustration, describe what you see."
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"type": "image_url",
|
|
146
|
+
"image_url": {
|
|
147
|
+
"url": f"data:{mime_type};base64,{base64_image}"
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
]
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
# Get response from LLM
|
|
154
|
+
response_text = ""
|
|
155
|
+
for chunk in send_prompt([message]):
|
|
156
|
+
chunk_content = chunk.choices[0].delta.content
|
|
157
|
+
if chunk_content:
|
|
158
|
+
response_text += chunk_content
|
|
159
|
+
|
|
160
|
+
return response_text.strip()
|
|
161
|
+
|
|
162
|
+
|
|
108
163
|
def append_headings(classifier, param, heading_name):
|
|
109
164
|
sub_directory = Classifier.get_sub_directory(classifier)
|
|
110
165
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# version.py
|
|
2
|
-
__version__ = "0.1.9.
|
|
2
|
+
__version__ = "0.1.9.84" # fith parameter like .0 for local install test purposes only. official numbers should be 4 digit numbers
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ara_cli
|
|
3
|
-
Version: 0.1.9.
|
|
3
|
+
Version: 0.1.9.84
|
|
4
4
|
Summary: Powerful, open source command-line tool for managing, structuring and automating software development artifacts in line with Business-Driven Development (BDD) and AI-assisted processes
|
|
5
5
|
Description-Content-Type: text/markdown
|
|
6
6
|
Requires-Dist: litellm
|
|
@@ -60,6 +60,8 @@ ara_cli/artefact_models/vision_artefact_model.py
|
|
|
60
60
|
ara_cli/commands/__init__.py
|
|
61
61
|
ara_cli/commands/command.py
|
|
62
62
|
ara_cli/commands/extract_command.py
|
|
63
|
+
ara_cli/commands/load_command.py
|
|
64
|
+
ara_cli/commands/load_image_command.py
|
|
63
65
|
ara_cli/templates/agile.artefacts
|
|
64
66
|
ara_cli/templates/template.businessgoal.prompt_log.md
|
|
65
67
|
ara_cli/templates/template.capability.prompt_log.md
|