ara-cli 0.1.9.73__tar.gz → 0.1.9.74__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.

Potentially problematic release.


This version of ara-cli might be problematic. Click here for more details.

Files changed (165) hide show
  1. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/PKG-INFO +1 -1
  2. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/ara_command_action.py +15 -15
  3. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/ara_command_parser.py +2 -1
  4. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_autofix.py +77 -46
  5. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_creator.py +1 -1
  6. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_models/artefact_model.py +26 -7
  7. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_models/artefact_templates.py +47 -31
  8. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_models/feature_artefact_model.py +2 -0
  9. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_scan.py +0 -1
  10. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/chat.py +23 -5
  11. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/template_manager.py +3 -8
  12. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/version.py +1 -1
  13. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli.egg-info/PKG-INFO +1 -1
  14. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli.egg-info/SOURCES.txt +0 -10
  15. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/tests/test_artefact_autofix.py +289 -25
  16. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/tests/test_chat.py +33 -13
  17. ara_cli-0.1.9.73/ara_cli/templates/template.businessgoal +0 -10
  18. ara_cli-0.1.9.73/ara_cli/templates/template.capability +0 -10
  19. ara_cli-0.1.9.73/ara_cli/templates/template.epic +0 -15
  20. ara_cli-0.1.9.73/ara_cli/templates/template.example +0 -6
  21. ara_cli-0.1.9.73/ara_cli/templates/template.feature +0 -26
  22. ara_cli-0.1.9.73/ara_cli/templates/template.issue +0 -14
  23. ara_cli-0.1.9.73/ara_cli/templates/template.keyfeature +0 -15
  24. ara_cli-0.1.9.73/ara_cli/templates/template.task +0 -6
  25. ara_cli-0.1.9.73/ara_cli/templates/template.userstory +0 -17
  26. ara_cli-0.1.9.73/ara_cli/templates/template.vision +0 -14
  27. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/MANIFEST.in +0 -0
  28. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/README.md +0 -0
  29. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/__init__.py +0 -0
  30. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/__main__.py +0 -0
  31. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/ara_config.py +0 -0
  32. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_deleter.py +0 -0
  33. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_fuzzy_search.py +0 -0
  34. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_link_updater.py +0 -0
  35. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_lister.py +0 -0
  36. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_models/__init__.py +0 -0
  37. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_models/artefact_load.py +0 -0
  38. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_models/artefact_mapping.py +0 -0
  39. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_models/businessgoal_artefact_model.py +0 -0
  40. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_models/capability_artefact_model.py +0 -0
  41. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_models/epic_artefact_model.py +0 -0
  42. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_models/example_artefact_model.py +0 -0
  43. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_models/issue_artefact_model.py +0 -0
  44. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_models/keyfeature_artefact_model.py +0 -0
  45. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_models/serialize_helper.py +0 -0
  46. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_models/task_artefact_model.py +0 -0
  47. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_models/userstory_artefact_model.py +0 -0
  48. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_models/vision_artefact_model.py +0 -0
  49. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_reader.py +0 -0
  50. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/artefact_renamer.py +0 -0
  51. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/classifier.py +0 -0
  52. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/codefusionretriever.py +0 -0
  53. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/codehierachieretriever.py +0 -0
  54. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/commandline_completer.py +0 -0
  55. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/directory_navigator.py +0 -0
  56. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/file_classifier.py +0 -0
  57. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/file_lister.py +0 -0
  58. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/filename_validator.py +0 -0
  59. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/list_filter.py +0 -0
  60. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/output_suppressor.py +0 -0
  61. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/prompt_chat.py +0 -0
  62. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/prompt_extractor.py +0 -0
  63. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/prompt_handler.py +0 -0
  64. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/prompt_rag.py +0 -0
  65. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/run_file_lister.py +0 -0
  66. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/tag_extractor.py +0 -0
  67. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/agile.artefacts +0 -0
  68. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/blueprints/complete_pytest_unittest.blueprint.md +0 -0
  69. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/blueprints/empty.blueprint.md +0 -0
  70. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/blueprints/task_todo_list_C4_architecture_analysis.blueprint.md +0 -0
  71. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/blueprints/task_todo_list_implement_feature_BDD_way.blueprint.md +0 -0
  72. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/commands/architecture_C4_analysis.commands.md +0 -0
  73. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/commands/architecture_radon_cc_score.commands.md +0 -0
  74. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/commands/architecture_radon_halstead_v.commands.md +0 -0
  75. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/commands/architecture_radon_maintainability_score.commands.md +0 -0
  76. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/commands/artefact_classification.commands.md +0 -0
  77. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/commands/artefact_extension.commands.md +0 -0
  78. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/commands/artefact_formulation.commands.md +0 -0
  79. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/commands/behave_step_generation.commands.md +0 -0
  80. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/commands/code_generation_complex.commands.md +0 -0
  81. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/commands/code_generation_simple.commands.md +0 -0
  82. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/commands/empty.commands.md +0 -0
  83. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/commands/error_fixing.commands.md +0 -0
  84. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/commands/feature_file_update.commands.md +0 -0
  85. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/commands/feature_formulation.commands.md +0 -0
  86. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/commands/js_code_generation_simple.commands.md +0 -0
  87. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/commands/refactoring.commands.md +0 -0
  88. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/commands/refactoring_analysis.commands.md +0 -0
  89. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/commands/reverse_engineer_feature_file.commands.md +0 -0
  90. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/commands/reverse_engineer_program_flow.commands.md +0 -0
  91. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/intentions/classify_task.intention.md +0 -0
  92. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/intentions/empty.intention.md +0 -0
  93. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/intentions/error_fixing.intention.md +0 -0
  94. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/intentions/feature_fix_steps_for_scenario.intention.md +0 -0
  95. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/intentions/feature_formulation.intention.md +0 -0
  96. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/intentions/feature_reverse_formulation_from_code.intention.md +0 -0
  97. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/intentions/feature_scenario_implementation.intention.md +0 -0
  98. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/intentions/feature_scenario_implementation_update.intention.md +0 -0
  99. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/intentions/feature_scenario_outline_extension.intention.md +0 -0
  100. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/intentions/feature_update_formulation.intention.md +0 -0
  101. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/intentions/fibonacci_example_implementation.intention.md +0 -0
  102. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/intentions/js_implementation_from_task_description.intention.md +0 -0
  103. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/intentions/js_steps_implementation.intention.md +0 -0
  104. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/intentions/python_cli_implementation_with_test.intention.md +0 -0
  105. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/intentions/python_code_understanding.intention.md +0 -0
  106. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/intentions/task_implementation.intention.md +0 -0
  107. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/intentions/task_prompt_control_by_status.intention.md +0 -0
  108. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/intentions/task_stepwise_implementation_by_number.intention.md +0 -0
  109. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/intentions/task_stepwise_implementation_by_status.intention.md +0 -0
  110. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/rules/architecture_analyst.rules.md +0 -0
  111. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/rules/code_analyst.rules.md +0 -0
  112. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/rules/empty.rules.md +0 -0
  113. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/rules/error_analyst.rules.md +0 -0
  114. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/rules/gherkin_expert.rules.md +0 -0
  115. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/rules/js_expert_developer.rules.md +0 -0
  116. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/rules/product_owner.rules.md +0 -0
  117. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/rules/python_behave.rules.md +0 -0
  118. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/prompt-modules/rules/python_developer.rules.md +0 -0
  119. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/specification_breakdown_files/template.concept.exploration.md +0 -0
  120. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/specification_breakdown_files/template.concept.md +0 -0
  121. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/specification_breakdown_files/template.customer.exploration.md +0 -0
  122. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/specification_breakdown_files/template.customer.md +0 -0
  123. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/specification_breakdown_files/template.persona.exploration.md +0 -0
  124. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/specification_breakdown_files/template.persona.md +0 -0
  125. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/specification_breakdown_files/template.step.exploration.md +0 -0
  126. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/specification_breakdown_files/template.step.md +0 -0
  127. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/specification_breakdown_files/template.technology.exploration.md +0 -0
  128. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/specification_breakdown_files/template.technology.md +0 -0
  129. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/template.businessgoal.prompt_log.md +0 -0
  130. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/template.capability.prompt_log.md +0 -0
  131. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/template.epic.prompt_log.md +0 -0
  132. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/template.example.prompt_log.md +0 -0
  133. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/template.feature.prompt_log.md +0 -0
  134. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/template.issue.prompt_log.md +0 -0
  135. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/template.keyfeature.prompt_log.md +0 -0
  136. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/template.steps.prompt_log.md +0 -0
  137. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/template.task.prompt_log.md +0 -0
  138. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/template.userstory.prompt_log.md +0 -0
  139. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/templates/template.vision.prompt_log.md +0 -0
  140. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli/update_config_prompt.py +0 -0
  141. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli.egg-info/dependency_links.txt +0 -0
  142. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli.egg-info/entry_points.txt +0 -0
  143. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli.egg-info/requires.txt +0 -0
  144. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/ara_cli.egg-info/top_level.txt +0 -0
  145. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/docker/base/requirements.txt +0 -0
  146. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/setup.cfg +0 -0
  147. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/setup.py +0 -0
  148. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/tests/__init__.py +0 -0
  149. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/tests/test_ara_command_action.py +0 -0
  150. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/tests/test_ara_config.py +0 -0
  151. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/tests/test_artefact_fuzzy_search.py +0 -0
  152. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/tests/test_artefact_link_updater.py +0 -0
  153. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/tests/test_artefact_lister.py +0 -0
  154. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/tests/test_artefact_reader.py +0 -0
  155. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/tests/test_artefact_renamer.py +0 -0
  156. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/tests/test_artefact_scan.py +0 -0
  157. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/tests/test_classifier.py +0 -0
  158. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/tests/test_directory_navigator.py +0 -0
  159. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/tests/test_file_classifier.py +0 -0
  160. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/tests/test_file_creator.py +0 -0
  161. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/tests/test_file_lister.py +0 -0
  162. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/tests/test_list_filter.py +0 -0
  163. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/tests/test_tag_extractor.py +0 -0
  164. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/tests/test_template_manager.py +0 -0
  165. {ara_cli-0.1.9.73 → ara_cli-0.1.9.74}/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.73
3
+ Version: 0.1.9.74
4
4
  Requires-Dist: litellm
5
5
  Requires-Dist: llama-index
6
6
  Requires-Dist: llama-index-llms-openai
@@ -347,6 +347,7 @@ def reconnect_action(args):
347
347
  from ara_cli.artefact_models.artefact_load import artefact_from_content
348
348
  from ara_cli.artefact_models.artefact_model import Contribution
349
349
  from ara_cli.artefact_reader import ArtefactReader
350
+ from ara_cli.file_classifier import FileClassifier
350
351
  from ara_cli.artefact_fuzzy_search import find_closest_rule
351
352
 
352
353
  classifier = args.classifier
@@ -359,31 +360,29 @@ def reconnect_action(args):
359
360
 
360
361
  feedback_message = f"Updated contribution of {classifier} '{artefact_name}' to {parent_classifier} '{parent_name}'"
361
362
 
362
- content, artefact_info = ArtefactReader.read_artefact_data(
363
+ file_classifier = FileClassifier(os)
364
+ classified_file_info = file_classifier.classify_files()
365
+
366
+ artefact = ArtefactReader.read_artefact(
363
367
  artefact_name=artefact_name,
364
- classifier=classifier
368
+ classifier=classifier,
369
+ classified_file_info=classified_file_info
365
370
  )
366
- if not content:
371
+
372
+ if not artefact:
367
373
  print(read_error_message)
368
374
  return
369
375
 
370
- parent_content, parent_info = ArtefactReader.read_artefact_data(
376
+ parent = ArtefactReader.read_artefact(
371
377
  artefact_name=parent_name,
372
- classifier=parent_classifier
378
+ classifier=parent_classifier,
379
+ classified_file_info=classified_file_info
373
380
  )
374
- if not parent_content:
381
+
382
+ if not parent:
375
383
  print(read_error_message)
376
384
  return
377
385
 
378
- artefact = artefact_from_content(
379
- content=content,
380
- )
381
- artefact._file_path = artefact_info["file_path"]
382
-
383
- parent = artefact_from_content(
384
- content=parent_content
385
- )
386
-
387
386
  contribution = Contribution(
388
387
  artefact_name=parent.title,
389
388
  classifier=parent.artefact_type
@@ -603,6 +602,7 @@ def autofix_action(args):
603
602
  file_path,
604
603
  classifier,
605
604
  reason,
605
+ single_pass=args.single_pass,
606
606
  deterministic=run_deterministic,
607
607
  non_deterministic=run_non_deterministic,
608
608
  classified_artefact_info=classified_artefact_info
@@ -229,7 +229,8 @@ def scan_parser(subparsers):
229
229
 
230
230
 
231
231
  def autofix_parser(subparsers):
232
- autofix_parser = subparsers.add_parser("autofix", help="Fix ARA tree with llm models for scanned artefacts with ara scan command.")
232
+ autofix_parser = subparsers.add_parser("autofix", help="Fix ARA tree with llm models for scanned artefacts with ara scan command. By default three attemps for every file.")
233
+ autofix_parser.add_argument("--single-pass", action="store_true", help="Run the autofix once for every scaned file.")
233
234
  determinism_group = autofix_parser.add_mutually_exclusive_group()
234
235
  determinism_group.add_argument("--deterministic", "-d", action="store_true", help="Run only deterministic fixes e.g Title-FileName Mismatch fix")
235
236
  determinism_group.add_argument("--non-deterministic", "-nd", action="store_true", help="Run only non-deterministic fixes")
@@ -1,3 +1,4 @@
1
+ from ara_cli.artefact_scan import check_file
1
2
  from ara_cli.artefact_fuzzy_search import (
2
3
  find_closest_name_matches,
3
4
  extract_artefact_names_of_classifier,
@@ -159,7 +160,7 @@ def ask_for_correct_contribution(
159
160
 
160
161
  print(
161
162
  f"Can not determine a match for contribution {contribution_message}. "
162
- f"Please provide a valid contribution or contribution will be empty (<classifier> <file_name>)."
163
+ f"Please provide a valid contribution or contribution will be empty ([classifier] [file_name])."
163
164
  )
164
165
 
165
166
  user_input = input().strip()
@@ -179,7 +180,9 @@ def ask_for_correct_contribution(
179
180
  def ask_for_contribution_choice(
180
181
  choices, artefact_info: Optional[tuple[str, str]] = None
181
182
  ) -> Optional[str]:
182
- artefact_name, artefact_classifier = artefact_info
183
+ artefact_name, artefact_classifier = (
184
+ artefact_info if artefact_info else (None, None)
185
+ )
183
186
  message = "Found multiple close matches for the contribution"
184
187
  if artefact_name and artefact_classifier:
185
188
  message += f" of the {artefact_classifier} '{artefact_name}'"
@@ -379,68 +382,96 @@ def apply_autofix(
379
382
  file_path: str,
380
383
  classifier: str,
381
384
  reason: str,
385
+ single_pass: bool = False,
382
386
  deterministic: bool = True,
383
387
  non_deterministic: bool = True,
384
388
  classified_artefact_info: Optional[Dict[str, List[Dict[str, str]]]] = None,
385
389
  ) -> bool:
386
- artefact_text = read_artefact(file_path)
387
- if artefact_text is None:
388
- return False
389
-
390
+ """
391
+ Applies fixes to a single artefact file iteratively until it is valid
392
+ or a fix cannot be applied. If single_pass is True, it runs for only one attempt.
393
+ """
390
394
  artefact_type, artefact_class = determine_artefact_type_and_class(classifier)
391
395
  if artefact_type is None or artefact_class is None:
392
396
  return False
393
397
 
394
398
  if classified_artefact_info is None:
395
399
  file_classifier = FileClassifier(os)
396
- classified_file_info = file_classifier.classified_files()
400
+ classified_artefact_info = file_classifier.classify_files()
397
401
 
398
- deterministic_markers_to_functions = {
399
- "Filename-Title Mismatch": fix_title_mismatch,
400
- "Invalid Contribution Reference": fix_contribution,
401
- }
402
+ if single_pass:
403
+ max_attempts = 1
404
+ print(f"Single-pass mode enabled for {file_path}. Running for 1 attempt.")
405
+ else:
406
+ max_attempts = 3
407
+
408
+ for attempt in range(max_attempts):
409
+ is_valid, current_reason = check_file(file_path, artefact_class, classified_artefact_info)
410
+
411
+ if is_valid:
412
+ print(f"✅ Artefact at {file_path} is now valid.")
413
+ return True
414
+
415
+ print(f"Attempting to fix {file_path} (Attempt {attempt + 1}/{max_attempts})...")
416
+ print(f" Reason: {current_reason}")
417
+
418
+ artefact_text = read_artefact(file_path)
419
+ if artefact_text is None:
420
+ return False
421
+
422
+ deterministic_markers_to_functions = {
423
+ "Filename-Title Mismatch": fix_title_mismatch,
424
+ "Invalid Contribution Reference": fix_contribution,
425
+ }
402
426
 
403
- try:
404
427
  deterministic_issue = next(
405
428
  (
406
429
  marker
407
- for marker in deterministic_markers_to_functions.keys()
408
- if marker in reason
430
+ for marker in deterministic_markers_to_functions
431
+ if marker in current_reason
409
432
  ),
410
433
  None,
411
434
  )
412
- except StopIteration:
413
- pass
414
- is_deterministic_issue = deterministic_issue is not None
415
-
416
- if deterministic and is_deterministic_issue:
417
- print(f"Attempting deterministic fix for {file_path}...")
418
- corrected_text = deterministic_markers_to_functions[deterministic_issue](
419
- file_path=file_path,
420
- artefact_text=artefact_text,
421
- artefact_class=artefact_class,
422
- classified_artefact_info=classified_artefact_info,
423
- )
424
- write_corrected_artefact(file_path, corrected_text)
425
- return True
426
-
427
- # Attempt non-deterministic fix if requested and the issue is NOT deterministic
428
- if non_deterministic and not is_deterministic_issue:
429
- print(f"Attempting non-deterministic (LLM) fix for {file_path}...")
430
- prompt = construct_prompt(artefact_type, reason, file_path, artefact_text)
431
- try:
432
- corrected_artefact = run_agent(prompt, artefact_class)
433
- corrected_text = corrected_artefact.serialize()
434
- write_corrected_artefact(file_path, corrected_text)
435
- return True
436
- except Exception as e:
437
- print(f"LLM agent failed to fix artefact at {file_path}: {e}")
435
+
436
+ corrected_text = None
437
+
438
+ if deterministic and deterministic_issue:
439
+ print(f"Applying deterministic fix for '{deterministic_issue}'...")
440
+ fix_function = deterministic_markers_to_functions[deterministic_issue]
441
+ corrected_text = fix_function(
442
+ file_path=file_path,
443
+ artefact_text=artefact_text,
444
+ artefact_class=artefact_class,
445
+ classified_artefact_info=classified_artefact_info,
446
+ )
447
+
448
+ elif non_deterministic and not deterministic_issue:
449
+ print("Applying non-deterministic (LLM) fix...")
450
+ prompt = construct_prompt(artefact_type, current_reason, file_path, artefact_text)
451
+ try:
452
+ corrected_artefact = run_agent(prompt, artefact_class)
453
+ corrected_text = corrected_artefact.serialize()
454
+ except Exception as e:
455
+ print(f" ❌ LLM agent failed to fix artefact at {file_path}: {e}")
456
+ return False
457
+
458
+ else:
459
+ if not non_deterministic and not deterministic_issue:
460
+ print(f"Skipping non-deterministic fix for {file_path} as per request.")
461
+ else:
462
+ print(f"Skipping fix for {file_path} as per request flags.")
438
463
  return False
439
464
 
440
- # Log if a fix was skipped due to flags
441
- if is_deterministic_issue and not deterministic:
442
- print(f"Skipping deterministic fix for {file_path} as per request.")
443
- elif not is_deterministic_issue and not non_deterministic:
444
- print(f"Skipping non-deterministic fix for {file_path} as per request.")
465
+ if corrected_text is not None and corrected_text.strip() != artefact_text.strip():
466
+ write_corrected_artefact(file_path, corrected_text)
467
+
468
+ print(" File modified. Re-classifying artefact information for next check...")
469
+ file_classifier = FileClassifier(os)
470
+ classified_artefact_info = file_classifier.classify_files()
471
+
472
+ else:
473
+ print(" Fixing attempt did not alter the file. Stopping to prevent infinite loop.")
474
+ return False
445
475
 
446
- return False
476
+ print(f"❌ Failed to fix {file_path} after {max_attempts} attempts.")
477
+ return False
@@ -106,7 +106,7 @@ class ArtefactCreator:
106
106
  if not self.handle_existing_files(file_exists):
107
107
  return
108
108
 
109
- artefact = template_artefact_of_type(classifier, filename)
109
+ artefact = template_artefact_of_type(classifier, filename, False)
110
110
 
111
111
  if parent_classifier and parent_name:
112
112
  artefact.set_contribution(
@@ -1,5 +1,5 @@
1
1
  from pydantic import BaseModel, Field, field_validator, model_validator
2
- from typing import Optional, List, Literal, Union, Dict
2
+ from typing import Optional, List, Literal, Union, Dict, ClassVar
3
3
  from typing_extensions import Self
4
4
  from enum import Enum
5
5
  from abc import ABC, abstractmethod
@@ -47,13 +47,23 @@ class Contribution(BaseModel):
47
47
  description="Rule the contribution is using. The classifier of the parent must be userstory or epic if this is used"
48
48
  )
49
49
 
50
+ PLACEHOLDER_NAME: ClassVar[str] = "<filename or title of the artefact>"
51
+ PLACEHOLDER_CLASSIFIER: ClassVar[str] = "<agile requirement artefact category> <(optional in case the contribution is to an artefact that is detailed with rules)"
52
+ PLACEHOLDER_RULE: ClassVar[str] = "<rule as it is formulated>"
53
+
50
54
  @model_validator(mode="after")
51
55
  def validate_parent(self) -> Self:
52
-
53
56
  artefact_name = self.artefact_name
54
57
  classifier = self.classifier
55
58
  rule = self.rule
56
59
 
60
+ if (
61
+ artefact_name == Contribution.PLACEHOLDER_NAME
62
+ or classifier == Contribution.PLACEHOLDER_CLASSIFIER
63
+ or rule == Contribution.PLACEHOLDER_RULE
64
+ ):
65
+ return self
66
+
57
67
  if artefact_name:
58
68
  artefact_name = replace_space_with_underscore(artefact_name)
59
69
  if not artefact_name or not classifier:
@@ -68,7 +78,7 @@ class Contribution(BaseModel):
68
78
 
69
79
  @field_validator('artefact_name')
70
80
  def validate_artefact_name(cls, value):
71
- if not value:
81
+ if not value or value == Contribution.PLACEHOLDER_NAME:
72
82
  return value
73
83
  if ' ' in value:
74
84
  warnings.warn(message="artefact_name can not contain spaces. Replacing spaces with '_'")
@@ -77,7 +87,7 @@ class Contribution(BaseModel):
77
87
 
78
88
  @field_validator('classifier', mode='after')
79
89
  def validate_classifier(cls, v):
80
- if not v:
90
+ if not v or v == Contribution.PLACEHOLDER_CLASSIFIER:
81
91
  return v
82
92
  try:
83
93
  return ArtefactType(v)
@@ -91,12 +101,21 @@ class Contribution(BaseModel):
91
101
  if not line.startswith(contribution_line_start):
92
102
  raise ValueError(f"Contribution line '{line}' does not start with '{contribution_line_start}'")
93
103
 
104
+ parent_text = line[len(contribution_line_start):].strip()
105
+ rule_specifier = " using rule "
106
+
107
+ placeholder_line = f"{cls.PLACEHOLDER_NAME} {cls.PLACEHOLDER_CLASSIFIER}{rule_specifier}{cls.PLACEHOLDER_RULE}"
108
+ if parent_text == placeholder_line:
109
+ return cls(
110
+ artefact_name=cls.PLACEHOLDER_NAME,
111
+ classifier=cls.PLACEHOLDER_CLASSIFIER,
112
+ rule=cls.PLACEHOLDER_RULE
113
+ )
114
+
94
115
  artefact_name = None
95
116
  classifier = None
96
117
  rule = None
97
118
 
98
- parent_text = line[len(contribution_line_start):].strip()
99
- rule_specifier = " using rule "
100
119
  if rule_specifier in parent_text:
101
120
  parent_text, rule_text = parent_text.split(rule_specifier, 1)
102
121
  rule = rule_text
@@ -113,7 +132,7 @@ class Contribution(BaseModel):
113
132
  def serialize(self) -> str:
114
133
  if not self.classifier or not self.artefact_name:
115
134
  return ""
116
- artefact_type = Classifier.get_artefact_title(self.classifier)
135
+ artefact_type = Classifier.get_artefact_title(self.classifier) or self.classifier
117
136
  artefact_name = replace_underscore_with_space(self.artefact_name)
118
137
  contribution = f"{artefact_name} {artefact_type}"
119
138
  if self.rule:
@@ -1,4 +1,4 @@
1
- from ara_cli.artefact_models.artefact_model import ArtefactType, Artefact
1
+ from ara_cli.artefact_models.artefact_model import ArtefactType, Artefact, Contribution
2
2
  from ara_cli.artefact_models.vision_artefact_model import VisionArtefact, VisionIntent
3
3
  from ara_cli.artefact_models.businessgoal_artefact_model import BusinessgoalArtefact, BusinessgoalIntent
4
4
  from ara_cli.artefact_models.capability_artefact_model import CapabilityArtefact, CapabilityIntent
@@ -11,7 +11,15 @@ from ara_cli.artefact_models.task_artefact_model import TaskArtefact
11
11
  from ara_cli.artefact_models.issue_artefact_model import IssueArtefact
12
12
 
13
13
 
14
- def _default_vision(title: str) -> VisionArtefact:
14
+ def default_contribution() -> Contribution:
15
+ return Contribution(
16
+ artefact_name=Contribution.PLACEHOLDER_NAME,
17
+ classifier=Contribution.PLACEHOLDER_CLASSIFIER,
18
+ rule=Contribution.PLACEHOLDER_RULE
19
+ )
20
+
21
+
22
+ def _default_vision(title: str, use_default_contribution: bool) -> VisionArtefact:
15
23
  intent = VisionIntent(
16
24
  for_="<target customer>",
17
25
  who="<needs something>",
@@ -24,11 +32,12 @@ def _default_vision(title: str) -> VisionArtefact:
24
32
  tags=["sample_tag"],
25
33
  title=title,
26
34
  description="<further optional description to understand the vision, markdown capable text formatting>",
27
- intent=intent
35
+ intent=intent,
36
+ contribution=default_contribution() if use_default_contribution else None
28
37
  )
29
38
 
30
39
 
31
- def _default_businessgoal(title: str) -> BusinessgoalArtefact:
40
+ def _default_businessgoal(title: str, use_default_contribution: bool) -> BusinessgoalArtefact:
32
41
  intent = BusinessgoalIntent(
33
42
  in_order_to="<reach primarily a monetary business goal>",
34
43
  as_a="<business related role>",
@@ -37,26 +46,26 @@ def _default_businessgoal(title: str) -> BusinessgoalArtefact:
37
46
  return BusinessgoalArtefact(
38
47
  tags=["sample_tag"],
39
48
  title=title,
40
- description="<further optional description to understand the vision, markdown capable text formatting>",
41
- intent=intent
49
+ description="<further optional description to understand the businessgoal, markdown capable text formatting>",
50
+ intent=intent,
51
+ contribution=default_contribution() if use_default_contribution else None
42
52
  )
43
53
 
44
54
 
45
- def _default_capability(title: str) -> CapabilityArtefact:
55
+ def _default_capability(title: str, use_default_contribution: bool) -> CapabilityArtefact:
46
56
  intent = CapabilityIntent(
47
- in_order_to="<reach primarily a monetary business goal>",
48
- as_a="<business related role>",
49
- to_be_able_to="<something that helps me to reach my monetary goal>"
57
+ to_be_able_to="<needed capability for stakeholders that are the enablers/relevant for reaching the business goal>"
50
58
  )
51
59
  return CapabilityArtefact(
52
60
  tags=["sample_tag"],
53
61
  title=title,
54
62
  description="<further optional description to understand the capability, markdown capable text formatting>",
55
- intent=intent
63
+ intent=intent,
64
+ contribution=default_contribution() if use_default_contribution else None
56
65
  )
57
66
 
58
67
 
59
- def _default_epic(title: str) -> EpicArtefact:
68
+ def _default_epic(title: str, use_default_contribution: bool) -> EpicArtefact:
60
69
  intent = EpicIntent(
61
70
  in_order_to="<achieve a benefit>",
62
71
  as_a="<(user) role>",
@@ -70,13 +79,14 @@ def _default_epic(title: str) -> EpicArtefact:
70
79
  return EpicArtefact(
71
80
  tags=["sample_tag"],
72
81
  title=title,
73
- description="<further optional description to understand the vision, markdown capable text formatting>",
82
+ description="<further optional description to understand the epic, markdown capable text formatting>",
74
83
  intent=intent,
75
- rules=rules
84
+ rules=rules,
85
+ contribution=default_contribution() if use_default_contribution else None
76
86
  )
77
87
 
78
88
 
79
- def _default_userstory(title: str) -> UserstoryArtefact:
89
+ def _default_userstory(title: str, use_default_contribution: bool) -> UserstoryArtefact:
80
90
  intent = UserstoryIntent(
81
91
  in_order_to="<achieve a benefit>",
82
92
  as_a="<(user) role>",
@@ -93,25 +103,27 @@ def _default_userstory(title: str) -> UserstoryArtefact:
93
103
  description="<further optional description to understand the userstory, markdown capable text formatting>",
94
104
  intent=intent,
95
105
  rules=rules,
96
- estimate="<story points, scale?>"
106
+ estimate="<story points, scale?>",
107
+ contribution=default_contribution() if use_default_contribution else None
97
108
  )
98
109
 
99
110
 
100
- def _default_example(title: str) -> ExampleArtefact:
111
+ def _default_example(title: str, use_default_contribution: bool) -> ExampleArtefact:
101
112
  return ExampleArtefact(
102
113
  tags=["sample_tag"],
103
114
  title=title,
104
115
  description="<further optional description to understand the example, markdown capable text formatting>",
116
+ contribution=default_contribution() if use_default_contribution else None
105
117
  )
106
118
 
107
119
 
108
- def _default_keyfeature(title: str) -> KeyfeatureArtefact:
120
+ def _default_keyfeature(title: str, use_default_contribution: bool) -> KeyfeatureArtefact:
109
121
  intent = KeyfeatureIntent(
110
122
  in_order_to="<support a capability or business goal>",
111
123
  as_a="<main stakeholder who will benefit>",
112
124
  i_want="<a product feature that helps me doing something so that I can achieve my named goal>"
113
125
  )
114
- description = """<further optional description to understand the capability, markdown capable text formatting, best practice is using
126
+ description = """<further optional description to understand the keyfeature, markdown capable text formatting, best practice is using
115
127
  GIVEN any precondition
116
128
  AND another precondition
117
129
  WHEN some action takes place
@@ -121,11 +133,12 @@ def _default_keyfeature(title: str) -> KeyfeatureArtefact:
121
133
  tags=["sample_tag"],
122
134
  title=title,
123
135
  description=description,
124
- intent=intent
136
+ intent=intent,
137
+ contribution=default_contribution() if use_default_contribution else None
125
138
  )
126
139
 
127
140
 
128
- def _default_feature(title: str) -> FeatureArtefact:
141
+ def _default_feature(title: str, use_default_contribution: bool) -> FeatureArtefact:
129
142
  intent = FeatureIntent(
130
143
  as_a="<user>",
131
144
  i_want_to="<do something | need something>",
@@ -169,27 +182,28 @@ def _default_feature(title: str) -> FeatureArtefact:
169
182
  ]
170
183
  )
171
184
  ]
172
- description = """<further optional description to understand
173
- the rule, no format defined, the example artefact is only a placeholder>"""
185
+ description = """<further optional description to understand the feature, no format defined, the example artefact is only a placeholder>"""
174
186
 
175
187
  return FeatureArtefact(
176
188
  tags=["sample_tag"],
177
189
  title=title,
178
190
  description=description,
179
191
  intent=intent,
180
- scenarios=scenarios
192
+ scenarios=scenarios,
193
+ contribution=default_contribution() if use_default_contribution else None
181
194
  )
182
195
 
183
196
 
184
- def _default_task(title: str) -> TaskArtefact:
197
+ def _default_task(title: str, use_default_contribution: bool) -> TaskArtefact:
185
198
  return TaskArtefact(
186
199
  status="to-do",
187
200
  title=title,
188
- description="<further optional description to understand the task, no format defined>"
201
+ description="<further optional description to understand the task, no format defined>",
202
+ contribution=default_contribution() if use_default_contribution else None
189
203
  )
190
204
 
191
205
 
192
- def _default_issue(title: str) -> IssueArtefact:
206
+ def _default_issue(title: str, use_default_contribution: bool) -> IssueArtefact:
193
207
  description = "<further free text description to understand the issue, no format defined>"
194
208
  additional_description = """*Optional descriptions of the issue in Gherkin style*
195
209
 
@@ -203,11 +217,12 @@ def _default_issue(title: str) -> IssueArtefact:
203
217
  tags=["sample_tag"],
204
218
  title=title,
205
219
  description=description,
206
- additional_description=additional_description
220
+ additional_description=additional_description,
221
+ contribution=default_contribution() if use_default_contribution else None
207
222
  )
208
223
 
209
224
 
210
- def template_artefact_of_type(artefact_type: ArtefactType, title: str = "<descriptive_title>") -> Artefact:
225
+ def template_artefact_of_type(artefact_type: ArtefactType, title: str = "<descriptive_title>", use_default_contribution: bool = True) -> Artefact:
211
226
  default_creation_functions = {
212
227
  ArtefactType.vision: _default_vision,
213
228
  ArtefactType.businessgoal: _default_businessgoal,
@@ -220,5 +235,6 @@ def template_artefact_of_type(artefact_type: ArtefactType, title: str = "<descri
220
235
  ArtefactType.task: _default_task,
221
236
  ArtefactType.issue: _default_issue
222
237
  }
223
-
224
- return default_creation_functions[artefact_type](title)
238
+ if artefact_type not in default_creation_functions.keys():
239
+ return None
240
+ return default_creation_functions[artefact_type](title, use_default_contribution)
@@ -138,6 +138,7 @@ class Scenario(BaseModel):
138
138
  @field_validator('title')
139
139
  def validate_title(cls, v: str) -> str:
140
140
  v = v.strip()
141
+ v = v.replace('_', ' ')
141
142
  if not v:
142
143
  raise ValueError("title must not be empty")
143
144
  return v
@@ -181,6 +182,7 @@ class ScenarioOutline(BaseModel):
181
182
  def validate_title(cls, v: str) -> str:
182
183
  if not v:
183
184
  raise ValueError("title must not be empty in a ScenarioOutline")
185
+ v = v.replace('_', ' ')
184
186
  return v
185
187
 
186
188
  @field_validator('steps', mode='before')
@@ -38,7 +38,6 @@ def check_file(file_path, artefact_class, classified_artefact_info=None):
38
38
  classifier=contribution.classifier
39
39
  )
40
40
 
41
- # Check if the referenced artefact exists
42
41
  if contribution.artefact_name not in all_artefact_names:
43
42
  reason = (f"Invalid Contribution Reference: The contribution references "
44
43
  f"'{contribution.classifier}' artefact '{contribution.artefact_name}' "
@@ -731,9 +731,27 @@ Start chatting (type 'HELP'/'h' for available commands, 'QUIT'/'q' to exit chat
731
731
  @cmd2.with_category(CATEGORY_CHAT_CONTROL)
732
732
  def do_LOAD_TEMPLATE(self, template_name):
733
733
  """Load artefact template"""
734
- directory = os.path.join(os.path.dirname(__file__), 'templates')
735
- pattern = f"template.{template_name}"
736
- file_type = "template"
737
- exclude_pattern = os.path.join(directory, "template.*.prompt_log.md")
734
+ from ara_cli.artefact_models.artefact_templates import template_artefact_of_type
738
735
 
739
- self._load_helper(directory, pattern, file_type, exclude_pattern)
736
+ artefact = template_artefact_of_type(''.join(template_name))
737
+ if not artefact:
738
+ return
739
+ write_content = artefact.serialize()
740
+ self.add_prompt_tag_if_needed(self.chat_name)
741
+ with open(self.chat_name, 'a', encoding='utf-8') as chat_file:
742
+ chat_file.write(write_content)
743
+ print(f"Loaded {template_name} artefact template")
744
+
745
+ def complete_LOAD_TEMPLATE(self, text, line, begidx, endidx):
746
+ return self._complete_classifiers(self, text, line, begidx, endidx)
747
+
748
+ def _complete_classifiers(self, text, line, begidx, endidx):
749
+ from ara_cli.classifier import Classifier
750
+
751
+ classifiers = Classifier.ordered_classifiers()
752
+ if not text:
753
+ completions = classifiers
754
+ else:
755
+ completions = [classifier for classifier in classifiers if classifier.startswith(text)]
756
+
757
+ return completions
@@ -4,6 +4,7 @@ from pathlib import Path
4
4
  from shutil import copy
5
5
  from ara_cli.classifier import Classifier
6
6
  from ara_cli.directory_navigator import DirectoryNavigator
7
+ from ara_cli.artefact_models.artefact_templates import template_artefact_of_type
7
8
 
8
9
 
9
10
  class TemplatePathManager:
@@ -30,14 +31,8 @@ class TemplatePathManager:
30
31
  ]
31
32
 
32
33
  def get_template_content(self, classifier):
33
- base_path = self.get_template_base_path()
34
-
35
- template_path = (base_path / f"template.{classifier}")
36
-
37
- with template_path.open('r', encoding='utf-8') as file:
38
- content = file.read()
39
-
40
- return content
34
+ artefact = template_artefact_of_type(classifier)
35
+ return artefact.serialize()
41
36
 
42
37
 
43
38
  class ArtefactFileManager:
@@ -1,2 +1,2 @@
1
1
  # version.py
2
- __version__ = "0.1.9.73" # fith parameter like .0 for local install test purposes only. official numbers should be 4 digit numbers
2
+ __version__ = "0.1.9.74" # 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.73
3
+ Version: 0.1.9.74
4
4
  Requires-Dist: litellm
5
5
  Requires-Dist: llama-index
6
6
  Requires-Dist: llama-index-llms-openai