janus-llm 4.3.1__py3-none-any.whl → 4.4.5__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.
Files changed (136) hide show
  1. janus/__init__.py +1 -1
  2. janus/__main__.py +1 -1
  3. janus/_tests/evaluator_tests/EvalReadMe.md +85 -0
  4. janus/_tests/evaluator_tests/incose_tests/incose_large_test.json +39 -0
  5. janus/_tests/evaluator_tests/incose_tests/incose_small_test.json +17 -0
  6. janus/_tests/evaluator_tests/inline_comment_tests/mumps_inline_comment_test.m +71 -0
  7. janus/_tests/test_cli.py +3 -2
  8. janus/cli/aggregate.py +135 -0
  9. janus/cli/cli.py +117 -0
  10. janus/cli/constants.py +49 -0
  11. janus/cli/database.py +289 -0
  12. janus/cli/diagram.py +207 -0
  13. janus/cli/document.py +183 -0
  14. janus/cli/embedding.py +122 -0
  15. janus/cli/llm.py +191 -0
  16. janus/cli/partition.py +134 -0
  17. janus/cli/pipeline.py +123 -0
  18. janus/cli/self_eval.py +147 -0
  19. janus/cli/translate.py +192 -0
  20. janus/converter/__init__.py +1 -1
  21. janus/converter/_tests/test_translate.py +7 -5
  22. janus/converter/chain.py +180 -0
  23. janus/converter/converter.py +444 -153
  24. janus/converter/diagram.py +8 -6
  25. janus/converter/document.py +27 -16
  26. janus/converter/evaluate.py +143 -144
  27. janus/converter/partition.py +2 -10
  28. janus/converter/requirements.py +4 -40
  29. janus/converter/translate.py +3 -59
  30. janus/embedding/collections.py +1 -1
  31. janus/language/alc/_tests/alc.asm +3779 -0
  32. janus/language/binary/_tests/hello.bin +0 -0
  33. janus/language/block.py +78 -14
  34. janus/language/file.py +1 -1
  35. janus/language/mumps/_tests/mumps.m +235 -0
  36. janus/language/treesitter/_tests/languages/fortran.f90 +416 -0
  37. janus/language/treesitter/_tests/languages/ibmhlasm.asm +16 -0
  38. janus/language/treesitter/_tests/languages/matlab.m +225 -0
  39. janus/llm/models_info.py +9 -1
  40. janus/metrics/_tests/asm_test_file.asm +10 -0
  41. janus/metrics/_tests/mumps_test_file.m +6 -0
  42. janus/metrics/_tests/test_treesitter_metrics.py +1 -1
  43. janus/metrics/metric.py +47 -124
  44. janus/metrics/prompts/clarity.txt +8 -0
  45. janus/metrics/prompts/completeness.txt +16 -0
  46. janus/metrics/prompts/faithfulness.txt +10 -0
  47. janus/metrics/prompts/hallucination.txt +16 -0
  48. janus/metrics/prompts/quality.txt +8 -0
  49. janus/metrics/prompts/readability.txt +16 -0
  50. janus/metrics/prompts/usefulness.txt +16 -0
  51. janus/parsers/code_parser.py +4 -4
  52. janus/parsers/doc_parser.py +12 -9
  53. janus/parsers/parser.py +7 -0
  54. janus/parsers/partition_parser.py +6 -4
  55. janus/parsers/reqs_parser.py +11 -8
  56. janus/parsers/uml.py +5 -4
  57. janus/prompts/prompt.py +2 -2
  58. janus/prompts/templates/README.md +30 -0
  59. janus/prompts/templates/basic_aggregation/human.txt +6 -0
  60. janus/prompts/templates/basic_aggregation/system.txt +1 -0
  61. janus/prompts/templates/basic_refinement/human.txt +14 -0
  62. janus/prompts/templates/basic_refinement/system.txt +1 -0
  63. janus/prompts/templates/diagram/human.txt +9 -0
  64. janus/prompts/templates/diagram/system.txt +1 -0
  65. janus/prompts/templates/diagram_with_documentation/human.txt +15 -0
  66. janus/prompts/templates/diagram_with_documentation/system.txt +1 -0
  67. janus/prompts/templates/document/human.txt +10 -0
  68. janus/prompts/templates/document/system.txt +1 -0
  69. janus/prompts/templates/document_cloze/human.txt +11 -0
  70. janus/prompts/templates/document_cloze/system.txt +1 -0
  71. janus/prompts/templates/document_cloze/variables.json +4 -0
  72. janus/prompts/templates/document_cloze/variables_asm.json +4 -0
  73. janus/prompts/templates/document_inline/human.txt +13 -0
  74. janus/prompts/templates/eval_prompts/incose/human.txt +32 -0
  75. janus/prompts/templates/eval_prompts/incose/system.txt +1 -0
  76. janus/prompts/templates/eval_prompts/incose/variables.json +3 -0
  77. janus/prompts/templates/eval_prompts/inline_comments/human.txt +49 -0
  78. janus/prompts/templates/eval_prompts/inline_comments/system.txt +1 -0
  79. janus/prompts/templates/eval_prompts/inline_comments/variables.json +3 -0
  80. janus/prompts/templates/micromanaged_mumps_v1.0/human.txt +23 -0
  81. janus/prompts/templates/micromanaged_mumps_v1.0/system.txt +3 -0
  82. janus/prompts/templates/micromanaged_mumps_v2.0/human.txt +28 -0
  83. janus/prompts/templates/micromanaged_mumps_v2.0/system.txt +3 -0
  84. janus/prompts/templates/micromanaged_mumps_v2.1/human.txt +29 -0
  85. janus/prompts/templates/micromanaged_mumps_v2.1/system.txt +3 -0
  86. janus/prompts/templates/multidocument/human.txt +15 -0
  87. janus/prompts/templates/multidocument/system.txt +1 -0
  88. janus/prompts/templates/partition/human.txt +22 -0
  89. janus/prompts/templates/partition/system.txt +1 -0
  90. janus/prompts/templates/partition/variables.json +4 -0
  91. janus/prompts/templates/pseudocode/human.txt +7 -0
  92. janus/prompts/templates/pseudocode/system.txt +7 -0
  93. janus/prompts/templates/refinement/fix_exceptions/human.txt +19 -0
  94. janus/prompts/templates/refinement/fix_exceptions/system.txt +1 -0
  95. janus/prompts/templates/refinement/format/code_format/human.txt +12 -0
  96. janus/prompts/templates/refinement/format/code_format/system.txt +1 -0
  97. janus/prompts/templates/refinement/format/requirements_format/human.txt +14 -0
  98. janus/prompts/templates/refinement/format/requirements_format/system.txt +1 -0
  99. janus/prompts/templates/refinement/hallucination/human.txt +13 -0
  100. janus/prompts/templates/refinement/hallucination/system.txt +1 -0
  101. janus/prompts/templates/refinement/reflection/human.txt +15 -0
  102. janus/prompts/templates/refinement/reflection/incose/human.txt +26 -0
  103. janus/prompts/templates/refinement/reflection/incose/system.txt +1 -0
  104. janus/prompts/templates/refinement/reflection/incose_deduplicate/human.txt +16 -0
  105. janus/prompts/templates/refinement/reflection/incose_deduplicate/system.txt +1 -0
  106. janus/prompts/templates/refinement/reflection/system.txt +1 -0
  107. janus/prompts/templates/refinement/revision/human.txt +16 -0
  108. janus/prompts/templates/refinement/revision/incose/human.txt +16 -0
  109. janus/prompts/templates/refinement/revision/incose/system.txt +1 -0
  110. janus/prompts/templates/refinement/revision/incose_deduplicate/human.txt +17 -0
  111. janus/prompts/templates/refinement/revision/incose_deduplicate/system.txt +1 -0
  112. janus/prompts/templates/refinement/revision/system.txt +1 -0
  113. janus/prompts/templates/refinement/uml/alc_fix_variables/human.txt +15 -0
  114. janus/prompts/templates/refinement/uml/alc_fix_variables/system.txt +2 -0
  115. janus/prompts/templates/refinement/uml/fix_connections/human.txt +15 -0
  116. janus/prompts/templates/refinement/uml/fix_connections/system.txt +2 -0
  117. janus/prompts/templates/requirements/human.txt +13 -0
  118. janus/prompts/templates/requirements/system.txt +2 -0
  119. janus/prompts/templates/retrieval/language_docs/human.txt +10 -0
  120. janus/prompts/templates/retrieval/language_docs/system.txt +1 -0
  121. janus/prompts/templates/simple/human.txt +16 -0
  122. janus/prompts/templates/simple/system.txt +3 -0
  123. janus/refiners/format.py +49 -0
  124. janus/refiners/refiner.py +113 -4
  125. janus/utils/enums.py +127 -112
  126. janus/utils/logger.py +2 -0
  127. {janus_llm-4.3.1.dist-info → janus_llm-4.4.5.dist-info}/METADATA +18 -18
  128. janus_llm-4.4.5.dist-info/RECORD +210 -0
  129. {janus_llm-4.3.1.dist-info → janus_llm-4.4.5.dist-info}/WHEEL +1 -1
  130. janus_llm-4.4.5.dist-info/entry_points.txt +3 -0
  131. janus/cli.py +0 -1488
  132. janus/metrics/_tests/test_llm.py +0 -90
  133. janus/metrics/llm_metrics.py +0 -202
  134. janus_llm-4.3.1.dist-info/RECORD +0 -115
  135. janus_llm-4.3.1.dist-info/entry_points.txt +0 -3
  136. {janus_llm-4.3.1.dist-info → janus_llm-4.4.5.dist-info}/LICENSE +0 -0
@@ -0,0 +1,26 @@
1
+ TASK:
2
+ ```
3
+ {prompt}
4
+ ```
5
+ --------------------
6
+ REQUIREMENTS:
7
+ ```
8
+ {completion}
9
+ ```
10
+ --------------------
11
+
12
+ Generate critique and suggestions for the provided REQUIREMENTS based on the above TASK. Your suggestions can include requests for added detail, corrections of factual errors, improved style, etc. to ensure that each of the requirements meet INCOSE standards, described below.
13
+
14
+ Do not rewrite the output yourself, only provide critique that can be acted on. Provide no further commentary or questions other than your feedback.
15
+
16
+ If every single one of the requirements meets the following INCOSE standards, return LGTM. "LGTM" must be returned on its own without further commentary. Be especially strict in your grading!
17
+
18
+ C1 - Necessary: The need or requirement statement defines an essential capability, characteristic, constraint, or quality factor needed to satisfy a lifecycle concept, need, source, or parent requirement.
19
+ C2 - Appropriate: The specific intent and amount of detail of the need or requirement statement is appropriate to the level (the level of abstraction, organization, or system architecture) of the entity to which it refers.
20
+ C3 - Unambiguous: Need statements must be written such that the stakeholder intent is clear. Requirement statements must be stated such that the requirement can be interpreted in only one way by all the intended stakeholders.
21
+ C4 - Complete: The requirement statement sufficiently describes the necessary capability, characteristic, constraint, or quality factor to meet the need, source, or parent requirement from which it was transformed without needing other information to understand the requirement.
22
+ C5 - Singular: The stakeholder need or requirement statement should state a single capability, characteristic, constraint, or quality factor.
23
+ C6 - Feasible: The need or requirement can be realized within entity constraints (for example: cost, schedule, technical, legal, ethical, safety) with acceptable risk.
24
+ C7 - Verifiable: The requirement statement is structured and worded such that its realization can be verified to the approving authority’s satisfaction.
25
+ C8 - Correct: The need statement must be an accurate representation of the lifecycle concept or source from which it was transformed. The requirement statement must be an accurate representation of the need, source, or parent requirement from which it was transformed.
26
+ C9 - Conforming: Individual needs and requirements should conform to an approved standard pattern and style guide or standard for writing and managing needs and requirements.
@@ -0,0 +1 @@
1
+ You are a software engineer and quality control professional tasked with reviewing and critiquing outputs from Large Language Models (LLMs). Given a task and an output, it is your job to generate critique and suggestions to improve the output. If the output fully meets the requirements of the task and is of high quality, you may approve it with a simple "LGTM".
@@ -0,0 +1,16 @@
1
+ TASK:
2
+ ```
3
+ {prompt}
4
+ ```
5
+ --------------------
6
+ REQUIREMENTS:
7
+ ```
8
+ {completion}
9
+ ```
10
+ --------------------
11
+
12
+ In order for software requirements to be useful for software modernization, they must be reasonably consise and not overly specific to the syntax of the legacy language of the code which they describe. With this in mind, for the provided TASK, suggest ways that the REQUIREMENTS could be less redundant. If the REQUIREMENTS include duplicated or unnecessary requirements, explain how some of them could be combined to reduce this number. If the REQUIREMENTS refer to specific aspects of the original coding language which would not be useful to a software developer porting the code to a new language, point it out.
13
+
14
+ Do not rewrite the output yourself, only provide critique that can be acted on. Provide no further commentary or questions other than your feedback.
15
+
16
+ If the requirements in the completion above are adequately consise, return LGTM. "LGTM" must be returned on its own without further commentary.
@@ -0,0 +1 @@
1
+ You are a software engineer and quality control professional tasked with reviewing and critiquing outputs from Large Language Models (LLMs). Given a task and an output, it is your job to generate critique and suggestions to improve the output. If the output fully meets the requirements of the task and is of high quality, you may approve it with a simple "LGTM".
@@ -0,0 +1 @@
1
+ You are a software engineer and quality control professional tasked with reviewing and critiquing outputs from Large Language Models (LLMs). Given a task and an output, it is your job to generate critique and suggestions to improve the output. If the output fully meets the requirements of the task and is of high quality, you may approve it with a simple "LGTM".
@@ -0,0 +1,16 @@
1
+ TASK:
2
+ ```
3
+ {prompt}
4
+ ```
5
+ --------------------
6
+ COMPLETION:
7
+ ```
8
+ {completion}
9
+ ```
10
+ --------------------
11
+ FEEDBACK:
12
+ ```
13
+ {reflection}
14
+ ```
15
+ --------------------
16
+ Improve the above COMPLETION of the given TASK by incorporating the provided FEEDBACK. Respond only with the revised output, following the format indicated in the original TASK description. Do not provide any additional commentary or questions about the critique.
@@ -0,0 +1,16 @@
1
+ TASK:
2
+ ```
3
+ {prompt}
4
+ ```
5
+ --------------------
6
+ REQUIREMENTS:
7
+ ```
8
+ {completion}
9
+ ```
10
+ --------------------
11
+ FEEDBACK:
12
+ ```
13
+ {reflection}
14
+ ```
15
+ --------------------
16
+ Improve the above REQUIREMENTS for the given TASK by incorporating the provided FEEDBACK. Respond only with the revised output, following the format indicated in the original TASK description. Do not provide any additional commentary or questions about the critique.
@@ -0,0 +1 @@
1
+ You are a software engineer and quality control professional tasked with improving outputs of Large Language Models according to human feedback. Given a task, a draft output, and some critique of that draft, it is your job to write a new version of the output that incorporates the provided suggestions and addresses any criticism.
@@ -0,0 +1,17 @@
1
+ TASK:
2
+ ```
3
+ {prompt}
4
+ ```
5
+ --------------------
6
+ COMPLETION:
7
+ ```
8
+ {completion}
9
+ ```
10
+ --------------------
11
+ FEEDBACK:
12
+ ```
13
+ {reflection}
14
+ ```
15
+ --------------------
16
+ Improve the above COMPLETION of the given TASK by incorporating the provided FEEDBACK. Respond only with the revised output, following the format indicated in the original TASK description. Do not provide any additional commentary or questions about the critique.
17
+ g: Individual needs and requirements should conform to an approved standard pattern and style guide or standard for writing and managing needs and requirements.
@@ -0,0 +1 @@
1
+ You are a software engineer and quality control professional tasked with improving outputs of Large Language Models according to human feedback. Given a task, a draft output, and some critique of that draft, it is your job to write a new version of the output that incorporates the provided suggestions and addresses any criticism.
@@ -0,0 +1 @@
1
+ You are a software engineer and quality control professional tasked with improving outputs of Large Language Models according to human feedback. Given a task, a draft output, and some critique of that draft, it is your job to write a new version of the output that incorporates the provided suggestions and addresses any criticism.
@@ -0,0 +1,15 @@
1
+ TASK:
2
+ ```
3
+ {prompt}
4
+ ```
5
+ --------------------
6
+ COMPLETION:
7
+ ```
8
+ {completion}
9
+ ```
10
+ --------------------
11
+ Find any instances of variables in the provided COMPLETION of the above TASK being referenced without their proper namespace. Variables should always be referenced as data_structure.variable. Data structures can include classes, DSECTS, files or other similar language features.
12
+
13
+ Do not rewrite the output yourself, only provide critique that can be acted on. Provide no further commentary or questions other than your feedback.
14
+
15
+ If the output fully meets the requirements of the task and no variables are referenced outside their appropriate class or DSECT, respond with LGTM. "LGTM" must be returned on its own without further commentary.
@@ -0,0 +1,2 @@
1
+ You are a software engineer and quality control professional tasked with reviewing and critiquing outputs from Large Language Models (LLMs). Given a task and an output, it is your job to generate critique and suggestions to improve the output.
2
+ You must detect any instances of variables being referenced in the UML without referencing their appropriate namespace (i.e. struct.var). If the output fully meets the requirements of the task and all variables are appropriately referenced, you may approve it with a simple "LGTM".
@@ -0,0 +1,15 @@
1
+ TASK:
2
+ ```
3
+ {prompt}
4
+ ```
5
+ --------------------
6
+ COMPLETION:
7
+ ```
8
+ {completion}
9
+ ```
10
+ --------------------
11
+ Find any instances of connections in the provided COMPLETION of the above TASK that do not accurately represent the control flow of the program. The COMPLETION should accurately capture the entire control flow of the original program in the TASK.
12
+
13
+ Do not rewrite the output yourself, only provide critique that can be acted on. Provide no further commentary or questions other than your feedback.
14
+
15
+ If the output fully meets the requirements of the task and the control flow of the program in the TASK is accurately reflected, respond with LGTM. "LGTM" must be returned on its own without further commentary.
@@ -0,0 +1,2 @@
1
+ You are a software engineer and quality control professional tasked with reviewing and critiquing outputs from Large Language Models (LLMs). Given a task and an output, it is your job to generate critique and suggestions to improve the output.
2
+ You must detect any connections in the UML that do not accurately represent the control flow. If the output fully meets the requirements of the task and the control flow is correctly represented, you may approve it with a simple "LGTM".
@@ -0,0 +1,13 @@
1
+ We are modernizing the following code so we need to extract software requirements to document its functionality.
2
+
3
+ These requirements are intended for developers to refactor and port this code to a modern programming language, so they should focus on functionality rather than specifics of its current legacy language.
4
+
5
+ Write the requirements in the style of an INCOSE software requirements specification document.
6
+
7
+ Here is the code:
8
+
9
+ ```
10
+ {SOURCE_CODE}
11
+ ```
12
+
13
+ {context}
@@ -0,0 +1,2 @@
1
+ Your purpose is to understand a source code file
2
+ and generate a software requirements specification document for it.
@@ -0,0 +1,10 @@
1
+ Are there any references in the following {SOURCE_LANGUAGE} source code to uncommon or obscure built-in language functionality e.g. stand library calls, opcode, etc. that you do not understand and may be present in a language reference manual?
2
+
3
+ If so, return a short, comma-separated list of functions or opcodes to reference the manual for. Do not return any basic language functionality.
4
+
5
+ If not, return 'NODOCS'. 'NODOCS' must be returned on its own without further commentary.
6
+
7
+ Here is the code:
8
+ ```
9
+ {SOURCE_CODE}
10
+ ```
@@ -0,0 +1 @@
1
+ You are a software engineer and quality control professional tasked with providing context to source code by suggesting aspects of the code which could be made more clear by referencing a language manual. Given some source code, it is your job to pick out standard library calls or instructions which could be clarified with a reference. If there are no such code features, you may skip with process with the response "NODOCS".
@@ -0,0 +1,16 @@
1
+ Please convert the following {SOURCE_LANGUAGE} .{FILE_SUFFIX} code found in between triple backticks
2
+ into {TARGET_LANGUAGE} code.
3
+
4
+ If the given code is incomplete, assume it is translated elsewhere.
5
+ If the given code is missing variable definitions, assume they are assigned elsewhere.
6
+ If there are incomplete statements that haven't been closed out, assume they are closed out in other translations.
7
+ If the code has comments, keep ALL of them.
8
+ If it only consists of ONLY comments, assume the code that is represented by those comments is translated elsewhere.
9
+
10
+ Some more things to remember:
11
+ (1) follow standard styling practice for the target language
12
+ (2) make sure the language is typed correctly
13
+
14
+ ```
15
+ {SOURCE_CODE}
16
+ ```
@@ -0,0 +1,3 @@
1
+ Your purpose is to convert {SOURCE_LANGUAGE} {FILE_SUFFIX} code
2
+ into runnable {TARGET_LANGUAGE} code ({TARGET_LANGUAGE} version
3
+ {TARGET_LANGUAGE_VERSION}).
@@ -0,0 +1,49 @@
1
+ from typing import Any
2
+
3
+ from langchain_core.output_parsers import StrOutputParser
4
+ from langchain_core.prompt_values import PromptValue
5
+ from langchain_core.runnables import RunnableSerializable
6
+
7
+ from janus.llm.models_info import MODEL_PROMPT_ENGINES, JanusModel
8
+ from janus.parsers.parser import JanusParser
9
+ from janus.refiners.refiner import JanusRefiner
10
+
11
+
12
+ class FormatRefiner(JanusRefiner):
13
+ format_chain: RunnableSerializable
14
+
15
+ def __init__(
16
+ self,
17
+ llm: JanusModel,
18
+ parser: JanusParser,
19
+ max_retries: int,
20
+ prompt_template_name: str,
21
+ ):
22
+ format_prompt = MODEL_PROMPT_ENGINES[llm.short_model_id](
23
+ source_language="text",
24
+ prompt_template=prompt_template_name,
25
+ ).prompt
26
+ format_chain = format_prompt | llm | StrOutputParser()
27
+ super().__init__(
28
+ format_chain=format_chain, parser=parser, max_retries=max_retries
29
+ )
30
+
31
+ def parse_completion(
32
+ self, completion: str, prompt_value: PromptValue, **kwargs
33
+ ) -> Any:
34
+ completion = self.format_chain.invoke(
35
+ dict(completion=completion, prompt=prompt_value.to_string())
36
+ )
37
+ return self.parser.parse(completion)
38
+
39
+
40
+ class CodeFormatRefiner(FormatRefiner):
41
+ def __init__(self, llm: JanusModel, parser: JanusParser, max_retries: int):
42
+ super().__init__(llm, parser, max_retries, "refinement/format/code_format")
43
+
44
+
45
+ class RequirementsFormatRefiner(FormatRefiner):
46
+ def __init__(self, llm: JanusModel, parser: JanusParser, max_retries: int):
47
+ super().__init__(
48
+ llm, parser, max_retries, "refinement/format/requirements_format"
49
+ )
janus/refiners/refiner.py CHANGED
@@ -3,6 +3,7 @@ from typing import Any
3
3
 
4
4
  from langchain.output_parsers import RetryWithErrorOutputParser
5
5
  from langchain_core.exceptions import OutputParserException
6
+ from langchain_core.messages import AIMessage
6
7
  from langchain_core.output_parsers import StrOutputParser
7
8
  from langchain_core.prompt_values import PromptValue
8
9
  from langchain_core.runnables import RunnableSerializable
@@ -108,7 +109,7 @@ class ReflectionRefiner(JanusRefiner):
108
109
  def parse_completion(
109
110
  self, completion: str, prompt_value: PromptValue, **kwargs
110
111
  ) -> Any:
111
- log.info(f"Reflection Prompt: {self.reflection_prompt_name}")
112
+ log.debug(f"Reflection Prompt: {self.reflection_prompt_name}")
112
113
  for retry_number in range(self.max_retries):
113
114
  reflection = self.reflection_chain.invoke(
114
115
  dict(
@@ -119,8 +120,117 @@ class ReflectionRefiner(JanusRefiner):
119
120
  if re.search(r"\bLGTM\b", reflection) is not None:
120
121
  return self.parser.parse(completion)
121
122
  if not retry_number:
122
- log.info(f"Completion:\n{completion}")
123
- log.info(f"Reflection:\n{reflection}")
123
+ log.debug(f"Completion:\n{completion}")
124
+ log.debug(f"Reflection:\n{reflection}")
125
+ completion = self.revision_chain.invoke(
126
+ dict(
127
+ prompt=prompt_value.to_string(),
128
+ completion=completion,
129
+ reflection=reflection,
130
+ )
131
+ )
132
+ log.debug(f"Revision:\n{completion}")
133
+
134
+ return self.parser.parse(completion)
135
+
136
+
137
+ class RequirementsReflectionRefiner(JanusRefiner):
138
+ """
139
+ This requirements-specific refiner is intended to address a common issue with
140
+ requirements reflection, where over the course of several reflection loops,
141
+ requirements lists grow increasingly verbose, eventually becoming too wordy
142
+ to be useful. To reduce this, this refiner interlaces an additional reflection
143
+ -> revision loop which de-duplicates requirements.
144
+ """
145
+
146
+ max_retries: int
147
+ reflection_chain: RunnableSerializable
148
+ revision_chain: RunnableSerializable
149
+ reflect_duplication_chain: RunnableSerializable
150
+ revise_duplication_chain: RunnableSerializable
151
+ reflection_prompt_name: str
152
+
153
+ def __init__(
154
+ self,
155
+ llm: JanusModel,
156
+ parser: JanusParser,
157
+ max_retries: int,
158
+ prompt_template_name: str = "refinement/reflection/incose",
159
+ ):
160
+ # Main reflection loop
161
+ reflection_prompt = MODEL_PROMPT_ENGINES[llm.short_model_id](
162
+ source_language="text",
163
+ prompt_template="refinement/reflection/incose",
164
+ ).prompt
165
+ revision_prompt = MODEL_PROMPT_ENGINES[llm.short_model_id](
166
+ source_language="text",
167
+ prompt_template="refinement/revision/incose",
168
+ ).prompt
169
+ # De-duplication loop
170
+ reflect_duplication_prompt = MODEL_PROMPT_ENGINES[llm.short_model_id](
171
+ source_language="text",
172
+ prompt_template="refinement/reflection/incose_deduplicate",
173
+ ).prompt
174
+ revise_duplication_prompt = MODEL_PROMPT_ENGINES[llm.short_model_id](
175
+ source_language="text",
176
+ prompt_template="refinement/revision/incose_deduplicate",
177
+ ).prompt
178
+
179
+ reflection_chain = reflection_prompt | llm | StrOutputParser()
180
+ revision_chain = revision_prompt | llm | StrOutputParser()
181
+ reflect_duplication_chain = reflect_duplication_prompt | llm | StrOutputParser()
182
+ revise_duplication_chain = revise_duplication_prompt | llm | StrOutputParser()
183
+ super().__init__(
184
+ reflection_prompt_name=prompt_template_name,
185
+ reflection_chain=reflection_chain,
186
+ revision_chain=revision_chain,
187
+ reflect_duplication_chain=reflect_duplication_chain,
188
+ revise_duplication_chain=revise_duplication_chain,
189
+ parser=parser,
190
+ max_retries=max_retries,
191
+ )
192
+
193
+ def parse_completion(
194
+ self, completion: str, prompt_value: PromptValue, **kwargs
195
+ ) -> Any:
196
+ log.debug(f"Reflection Prompt: {self.reflection_prompt_name}")
197
+ if isinstance(completion, AIMessage):
198
+ completion = completion.content
199
+ for retry_number in range(self.max_retries):
200
+ # First, check if the generated requirements are redundant or too specific
201
+ duplication_reflection = self.reflect_duplication_chain.invoke(
202
+ dict(
203
+ prompt=prompt_value.to_string(),
204
+ completion=completion,
205
+ )
206
+ )
207
+ if re.search(r"\bLGTM\b", duplication_reflection) is not None:
208
+ log.debug(
209
+ "No de-duplication suggested in reflection, "
210
+ "passing to next reflection step"
211
+ )
212
+ else:
213
+ completion = self.revise_duplication_chain.invoke(
214
+ dict(
215
+ prompt=prompt_value.to_string(),
216
+ completion=completion,
217
+ reflection=duplication_reflection,
218
+ )
219
+ )
220
+
221
+ # Once we're happy with the results or trimmed them down,
222
+ # continue with the typical reflection process,
223
+ # except with specific INCOSE-focused prompts
224
+ reflection = self.reflection_chain.invoke(
225
+ dict(
226
+ prompt=prompt_value.to_string(),
227
+ completion=completion,
228
+ )
229
+ )
230
+ if re.search(r"\bLGTM\b", reflection) is not None:
231
+ return self.parser.parse(completion)
232
+ if not retry_number:
233
+ log.debug(f"Completion:\n{completion}")
124
234
  completion = self.revision_chain.invoke(
125
235
  dict(
126
236
  prompt=prompt_value.to_string(),
@@ -128,7 +238,6 @@ class ReflectionRefiner(JanusRefiner):
128
238
  reflection=reflection,
129
239
  )
130
240
  )
131
- log.info(f"Revision:\n{completion}")
132
241
 
133
242
  return self.parser.parse(completion)
134
243