janus-llm 4.4.5__py3-none-any.whl → 4.5.4__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.
- janus/__init__.py +1 -1
- janus/cli/pipeline.py +6 -3
- janus/cli/self_eval.py +9 -0
- janus/converter/__init__.py +2 -0
- janus/converter/_tests/test_translate.py +1 -0
- janus/converter/chain.py +53 -133
- janus/converter/converter.py +199 -77
- janus/converter/diagram.py +5 -3
- janus/converter/document.py +10 -4
- janus/converter/evaluate.py +148 -113
- janus/converter/partition.py +4 -1
- janus/converter/passthrough.py +29 -0
- janus/converter/pool.py +74 -0
- janus/converter/requirements.py +4 -1
- janus/language/_tests/test_combine.py +1 -0
- janus/language/block.py +84 -3
- janus/llm/model_callbacks.py +6 -0
- janus/llm/models_info.py +19 -0
- janus/metrics/_tests/test_reading.py +48 -4
- janus/metrics/_tests/test_rouge_score.py +5 -11
- janus/metrics/reading.py +48 -28
- janus/metrics/rouge_score.py +21 -34
- janus/parsers/_tests/test_code_parser.py +1 -1
- janus/parsers/code_parser.py +2 -2
- janus/parsers/eval_parsers/incose_parser.py +3 -3
- janus/prompts/templates/cyclic/human.txt +16 -0
- janus/prompts/templates/cyclic/system.txt +1 -0
- janus/prompts/templates/eval_prompts/incose/human.txt +1 -1
- janus/prompts/templates/extract_variables/human.txt +5 -0
- janus/prompts/templates/extract_variables/system.txt +1 -0
- {janus_llm-4.4.5.dist-info → janus_llm-4.5.4.dist-info}/METADATA +3 -4
- {janus_llm-4.4.5.dist-info → janus_llm-4.5.4.dist-info}/RECORD +35 -29
- {janus_llm-4.4.5.dist-info → janus_llm-4.5.4.dist-info}/WHEEL +1 -1
- {janus_llm-4.4.5.dist-info → janus_llm-4.5.4.dist-info}/LICENSE +0 -0
- {janus_llm-4.4.5.dist-info → janus_llm-4.5.4.dist-info}/entry_points.txt +0 -0
janus/converter/evaluate.py
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
import json
|
2
2
|
import re
|
3
|
-
from copy import deepcopy
|
4
3
|
from pathlib import Path
|
5
|
-
from typing import Any
|
6
4
|
|
7
5
|
from langchain_core.runnables import Runnable, RunnableLambda, RunnableParallel
|
8
6
|
|
9
7
|
from janus.converter.converter import Converter
|
8
|
+
from janus.language.block import CodeBlock, TranslatedCodeBlock
|
10
9
|
from janus.language.combine import JsonCombiner
|
11
10
|
from janus.parsers.eval_parsers.incose_parser import IncoseParser
|
12
11
|
from janus.parsers.eval_parsers.inline_comment_parser import InlineCommentParser
|
@@ -51,7 +50,13 @@ class RequirementEvaluator(Evaluator):
|
|
51
50
|
|
52
51
|
"""
|
53
52
|
|
54
|
-
def __init__(
|
53
|
+
def __init__(
|
54
|
+
self,
|
55
|
+
eval_items_per_request: int | None = None,
|
56
|
+
input_types: str | set[str] = set(["requirements"]),
|
57
|
+
output_type: str = "requirements_eval",
|
58
|
+
**kwargs,
|
59
|
+
) -> None:
|
55
60
|
"""Initialize the Evaluator class
|
56
61
|
|
57
62
|
Arguments:
|
@@ -60,6 +65,7 @@ class RequirementEvaluator(Evaluator):
|
|
60
65
|
model_arguments: Additional arguments to pass to the LLM constructor.
|
61
66
|
max_prompts: The maximum number of prompts to try before giving up.
|
62
67
|
"""
|
68
|
+
kwargs.update(input_types=input_types, output_type=output_type)
|
63
69
|
super().__init__(**kwargs)
|
64
70
|
self.eval_items_per_request = eval_items_per_request
|
65
71
|
self._parser = IncoseParser()
|
@@ -78,55 +84,67 @@ class RequirementEvaluator(Evaluator):
|
|
78
84
|
context=self._retriever,
|
79
85
|
)
|
80
86
|
|
81
|
-
def
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
87
|
+
def translate_block(self, input_block: CodeBlock, failure_path: Path | None = None):
|
88
|
+
if len(input_block.previous_generations) == 0:
|
89
|
+
raise ValueError(
|
90
|
+
"Error: Evaluating requirements without previous generations"
|
91
|
+
)
|
92
|
+
if isinstance(input_block.previous_generations[-1], dict):
|
93
|
+
input_str = input_block.previous_generations[-1]["input"]
|
94
|
+
else:
|
95
|
+
input_str = input_block.previous_generations[-1].original.text
|
96
|
+
requirements = json.loads(input_block.text)
|
97
|
+
# The requirements are often a list of lists
|
98
|
+
if isinstance(requirements[0], list):
|
99
|
+
requirements = requirements[0]
|
100
|
+
if not requirements:
|
101
|
+
log.debug(f"[{input_block.name}] Skipping empty output")
|
102
|
+
return []
|
103
|
+
if (
|
104
|
+
not self.eval_items_per_request
|
105
|
+
or len(requirements) < self.eval_items_per_request
|
106
|
+
):
|
107
|
+
obj_str = json.dumps(
|
108
|
+
dict(
|
109
|
+
requirements=requirements,
|
110
|
+
code=input_str,
|
111
|
+
)
|
112
|
+
)
|
113
|
+
temp_block = self._split_text(obj_str, input_block.name)
|
114
|
+
translated_block = super().translate_block(temp_block, failure_path)
|
115
|
+
translated_block.original = input_block
|
116
|
+
translated_block.previous_generations = input_block.previous_generations
|
117
|
+
return translated_block
|
118
|
+
else:
|
119
|
+
translated_blocks = []
|
120
|
+
translated_str: str
|
121
|
+
translate_obj = {}
|
122
|
+
for i in range(0, len(requirements), self.eval_items_per_request):
|
123
|
+
working_requirements = requirements[i : i + self.eval_items_per_request]
|
124
|
+
obj_str = json.dumps(
|
125
|
+
dict(
|
126
|
+
requirements=working_requirements,
|
127
|
+
code=input_str,
|
101
128
|
)
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
translated_block = self.translate_block(temp_block, failure_path)
|
122
|
-
translated_block.previous_generations[-1] = obj
|
123
|
-
translated_block.original = self._janus_object_to_codeblock(
|
124
|
-
obj, name
|
125
|
-
)
|
126
|
-
results.append(translated_block)
|
127
|
-
else:
|
128
|
-
raise ValueError(f"Error: unable to find janus object: {type(o)}")
|
129
|
-
return results
|
129
|
+
)
|
130
|
+
temp_block = self._split_text(obj_str, input_block.name)
|
131
|
+
translated_block = super().translate_block(temp_block, failure_path)
|
132
|
+
translated_blocks.append(translated_block)
|
133
|
+
translate_obj.update(json.loads(translated_block.text))
|
134
|
+
translated_str = json.dumps(translate_obj)
|
135
|
+
|
136
|
+
translated_block = TranslatedCodeBlock(
|
137
|
+
input_block,
|
138
|
+
self._target_language,
|
139
|
+
self,
|
140
|
+
self._output_type,
|
141
|
+
self._output_label,
|
142
|
+
)
|
143
|
+
translated_block.text = translated_str
|
144
|
+
translated_block.children = translated_blocks
|
145
|
+
translated_block.tokens = self._llm.get_num_tokens(translated_str)
|
146
|
+
translated_block.translated = True
|
147
|
+
return translated_block
|
130
148
|
|
131
149
|
|
132
150
|
class InlineCommentEvaluator(Evaluator):
|
@@ -136,7 +154,13 @@ class InlineCommentEvaluator(Evaluator):
|
|
136
154
|
with an associated prompt.
|
137
155
|
"""
|
138
156
|
|
139
|
-
def __init__(
|
157
|
+
def __init__(
|
158
|
+
self,
|
159
|
+
eval_items_per_request: int | None = None,
|
160
|
+
input_types: str | set[str] = set(["cloze_comments"]),
|
161
|
+
output_type: str = "cloze_comments_eval",
|
162
|
+
**kwargs,
|
163
|
+
) -> None:
|
140
164
|
"""Initialize the Evaluator class
|
141
165
|
|
142
166
|
Arguments:
|
@@ -145,6 +169,7 @@ class InlineCommentEvaluator(Evaluator):
|
|
145
169
|
model_arguments: Additional arguments to pass to the LLM constructor.
|
146
170
|
max_prompts: The maximum number of prompts to try before giving up.
|
147
171
|
"""
|
172
|
+
kwargs.update(input_types=input_types, output_type=output_type)
|
148
173
|
super().__init__(**kwargs)
|
149
174
|
self._combiner = JsonCombiner()
|
150
175
|
self._parser = InlineCommentParser()
|
@@ -176,65 +201,75 @@ class InlineCommentEvaluator(Evaluator):
|
|
176
201
|
processed_str = re.sub(r"\s*<JANUS_PARTITION>\s*\n", "\n", input_str)
|
177
202
|
return processed_str.strip("\n"), missing_comments
|
178
203
|
|
179
|
-
def
|
204
|
+
def translate_block(self, input_block: CodeBlock, failure_path: Path | None = None):
|
180
205
|
comment_pattern = r"<(?:INLINE|BLOCK)_COMMENT \w{8}>.*$"
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
206
|
+
if len(input_block.previous_generations) == 0:
|
207
|
+
raise ValueError(
|
208
|
+
"Error: cannot evaluate block, no previous generations found"
|
209
|
+
)
|
210
|
+
if isinstance(input_block.previous_generations[-1], dict):
|
211
|
+
input_str = input_block.previous_generations[-1]["input"]
|
212
|
+
else:
|
213
|
+
input_str = input_block.previous_generations[-1].original.text
|
214
|
+
generated_comments = json.loads(input_block.text)
|
215
|
+
processed_input, missing_comments = self._process_comments(
|
216
|
+
input_str, generated_comments
|
217
|
+
)
|
218
|
+
if missing_comments:
|
219
|
+
log.info(f"[{input_block.name}] Warning: missing {missing_comments} comments")
|
220
|
+
comments = list(re.finditer(comment_pattern, processed_input, flags=re.MULTILINE))
|
221
|
+
if not comments:
|
222
|
+
log.info(f"[{input_block.name}] Skipping commentless block")
|
223
|
+
return []
|
224
|
+
if (
|
225
|
+
self.eval_items_per_request is None
|
226
|
+
or len(comments) < self.eval_items_per_request
|
227
|
+
):
|
228
|
+
temp_block = self._split_text(processed_input, input_block.name)
|
229
|
+
translated_block = super().translate_block(temp_block, failure_path)
|
230
|
+
translated_block.original = input_block
|
231
|
+
translated_block.previous_generations = input_block.previous_generations
|
232
|
+
return translated_block
|
233
|
+
else:
|
234
|
+
comment_group_indices = list(
|
235
|
+
range(0, len(comments), self.eval_items_per_request)
|
236
|
+
)
|
237
|
+
log.debug(
|
238
|
+
f"[{input_block.name}]"
|
239
|
+
f" Block contains more than {self.eval_items_per_request}"
|
240
|
+
f" comments, splitting {len(comments)} comments into"
|
241
|
+
f" {len(comment_group_indices)} groups"
|
242
|
+
)
|
243
|
+
translated_blocks = []
|
244
|
+
translated_str: str
|
245
|
+
translate_obj = {}
|
246
|
+
for comment_ind in comment_group_indices:
|
247
|
+
working_comments = comments[
|
248
|
+
comment_ind : comment_ind + self.eval_items_per_request
|
249
|
+
]
|
250
|
+
start_idx = working_comments[0].start()
|
251
|
+
end_idx = working_comments[-1].end()
|
252
|
+
prefix = processed_input[:start_idx]
|
253
|
+
keeper = processed_input[start_idx:end_idx]
|
254
|
+
suffix = processed_input[end_idx:]
|
255
|
+
|
256
|
+
# Strip all comment placeholders outside of the section of interest
|
257
|
+
prefix = re.sub(comment_pattern, "", prefix, flags=re.MULTILINE)
|
258
|
+
suffix = re.sub(comment_pattern, "", suffix, flags=re.MULTILINE)
|
259
|
+
temp_block = self._split_text(prefix + keeper + suffix, input_block.name)
|
260
|
+
translated_block = super().translate_block(temp_block, failure_path)
|
261
|
+
translated_blocks.append(translated_block)
|
262
|
+
translate_obj.update(json.loads(translated_block.text))
|
263
|
+
translated_str = json.dumps(translate_obj)
|
264
|
+
translated_block = TranslatedCodeBlock(
|
265
|
+
input_block,
|
266
|
+
self._target_language,
|
267
|
+
self,
|
268
|
+
self._output_type,
|
269
|
+
self._output_label,
|
270
|
+
)
|
271
|
+
translated_block.children = translated_blocks
|
272
|
+
translated_block.text = translated_str
|
273
|
+
translated_block.tokens = self._llm.get_num_tokens(translated_str)
|
274
|
+
translated_block.translated = True
|
275
|
+
return translated_block
|
janus/converter/partition.py
CHANGED
@@ -6,7 +6,10 @@ log = create_logger(__name__)
|
|
6
6
|
|
7
7
|
|
8
8
|
class Partitioner(Converter):
|
9
|
-
def __init__(
|
9
|
+
def __init__(
|
10
|
+
self, partition_token_limit: int, output_type: str = "partition", **kwargs
|
11
|
+
):
|
12
|
+
kwargs.update(output_type=output_type)
|
10
13
|
super().__init__(**kwargs)
|
11
14
|
self.set_prompts("partition")
|
12
15
|
self._load_model()
|
@@ -0,0 +1,29 @@
|
|
1
|
+
from pathlib import Path
|
2
|
+
|
3
|
+
from janus.converter.converter import Converter
|
4
|
+
from janus.language.block import CodeBlock, TranslatedCodeBlock
|
5
|
+
|
6
|
+
|
7
|
+
class ConverterPassthrough(Converter):
|
8
|
+
def __init__(self, **kwargs) -> None:
|
9
|
+
super().__init__(**kwargs)
|
10
|
+
|
11
|
+
def translate_block(
|
12
|
+
self, input_block: CodeBlock, failure_path: Path | None = None
|
13
|
+
) -> TranslatedCodeBlock:
|
14
|
+
self._output_label = input_block.block_label
|
15
|
+
self._output_type = input_block.block_type
|
16
|
+
res = super().translate_block(input_block, failure_path)
|
17
|
+
if isinstance(input_block.previous_generations[-1], dict):
|
18
|
+
res.original = self._split_text(
|
19
|
+
input_block.previous_generations[-1]["input"], res.name
|
20
|
+
)
|
21
|
+
else:
|
22
|
+
res.original = input_block.previous_generations[-1].original
|
23
|
+
res.previous_generations = input_block.previous_generations[:-1]
|
24
|
+
return res
|
25
|
+
|
26
|
+
def _add_translation(self, block: TranslatedCodeBlock) -> None:
|
27
|
+
block.text = block.original.text
|
28
|
+
block.tokens = block.original.tokens
|
29
|
+
block.translated = True
|
janus/converter/pool.py
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
from pathlib import Path
|
2
|
+
|
3
|
+
from janus.converter.converter import Converter
|
4
|
+
from janus.language.block import BlockCollection, CodeBlock, TranslatedCodeBlock
|
5
|
+
|
6
|
+
|
7
|
+
class ConverterPool(Converter):
|
8
|
+
def __init__(self, *args, **kwargs):
|
9
|
+
if len(args) == 0:
|
10
|
+
raise ValueError("Error: Converter chain must be passed at least 1 converter")
|
11
|
+
for converter in args:
|
12
|
+
if not isinstance(converter, Converter):
|
13
|
+
raise ValueError(f"Error: unrecognized type: {type(converter)}")
|
14
|
+
self._converters = args
|
15
|
+
if "source_language" in kwargs:
|
16
|
+
for c in self._converters:
|
17
|
+
c.set_source_language(kwargs["source_language"])
|
18
|
+
if "model" in kwargs:
|
19
|
+
for c in self._converters:
|
20
|
+
c.set_model(kwargs["model"])
|
21
|
+
super().__init__(**kwargs)
|
22
|
+
|
23
|
+
def translate_blocks(
|
24
|
+
self, input_blocks: CodeBlock | BlockCollection, failure_path: Path | None = None
|
25
|
+
):
|
26
|
+
output_blocks = []
|
27
|
+
for c in self._converters:
|
28
|
+
collection = c.translate_blocks(input_blocks)
|
29
|
+
for b in collection.blocks:
|
30
|
+
c._combiner.combine(b)
|
31
|
+
output_blocks += collection.blocks
|
32
|
+
return BlockCollection(output_blocks, input_blocks.previous_generations)
|
33
|
+
|
34
|
+
def _get_output_obj(
|
35
|
+
self,
|
36
|
+
block: TranslatedCodeBlock | BlockCollection | dict,
|
37
|
+
combine_children: bool = True,
|
38
|
+
include_previous_outputs: bool = True,
|
39
|
+
) -> dict[str, int | float | str | dict[str, str] | dict[str, float]]:
|
40
|
+
outputs = []
|
41
|
+
for b in block.blocks:
|
42
|
+
for c in self._converters:
|
43
|
+
if c == b.converter:
|
44
|
+
outputs.append(c._get_output_obj(b, c._combine_output, False))
|
45
|
+
break
|
46
|
+
|
47
|
+
def _get_input(block):
|
48
|
+
if isinstance(block, BlockCollection):
|
49
|
+
return self._combine_inputs([_get_input(b) for b in block.blocks])
|
50
|
+
return block.original.text or ""
|
51
|
+
|
52
|
+
out = dict(
|
53
|
+
input=_get_input(block),
|
54
|
+
metadata=dict(
|
55
|
+
cost=block.total_cost,
|
56
|
+
processing_time=block.total_processing_time,
|
57
|
+
num_requests=block.total_num_requests,
|
58
|
+
input_tokens=block.total_request_input_tokens,
|
59
|
+
output_tokens=block.total_request_output_tokens,
|
60
|
+
converter_name=self.__class__.__name__,
|
61
|
+
type=block.block_type,
|
62
|
+
label=block.block_label,
|
63
|
+
),
|
64
|
+
outputs=outputs,
|
65
|
+
)
|
66
|
+
if include_previous_outputs and len(block.previous_generations) > 0:
|
67
|
+
intermediate_outputs = [
|
68
|
+
self._get_output_obj(g, combine_children, False)
|
69
|
+
for g in block.previous_generations
|
70
|
+
if isinstance(g, dict)
|
71
|
+
]
|
72
|
+
if len(intermediate_outputs) > 0:
|
73
|
+
out["intermediate_outputs"] = intermediate_outputs
|
74
|
+
return out
|
janus/converter/requirements.py
CHANGED
@@ -12,7 +12,10 @@ class RequirementsDocumenter(Documenter):
|
|
12
12
|
A class that translates code from one programming language to its requirements.
|
13
13
|
"""
|
14
14
|
|
15
|
-
def __init__(
|
15
|
+
def __init__(
|
16
|
+
self, combine_output: bool = False, output_type: str = "requirements", **kwargs
|
17
|
+
):
|
18
|
+
kwargs.update(output_type=output_type)
|
16
19
|
super().__init__(combine_output=combine_output, **kwargs)
|
17
20
|
self.set_prompts("requirements")
|
18
21
|
self._combiner = ChunkCombiner()
|
janus/language/block.py
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
from functools import total_ordering
|
2
|
-
from typing import ForwardRef, Hashable, Optional, Tuple
|
2
|
+
from typing import TYPE_CHECKING, ForwardRef, Hashable, Optional, Tuple
|
3
3
|
|
4
4
|
from janus.language.node import NodeType
|
5
5
|
from janus.utils.logger import create_logger
|
6
6
|
|
7
|
+
if TYPE_CHECKING:
|
8
|
+
from janus.converter.converter import Converter
|
9
|
+
|
7
10
|
log = create_logger(__name__)
|
8
11
|
|
9
12
|
|
@@ -47,6 +50,8 @@ class CodeBlock:
|
|
47
50
|
affixes: Tuple[str, str] = ("", ""),
|
48
51
|
context_tags: dict[str, str] = {},
|
49
52
|
previous_generations: list["TranslatedCodeBlock"] = [],
|
53
|
+
block_type: str | None = None,
|
54
|
+
block_label: str | None = None,
|
50
55
|
) -> None:
|
51
56
|
self.id: Hashable = id
|
52
57
|
self.name: Optional[str] = name
|
@@ -67,6 +72,8 @@ class CodeBlock:
|
|
67
72
|
self.omit_prefix = True
|
68
73
|
self.omit_suffix = False
|
69
74
|
self.previous_generations = previous_generations
|
75
|
+
self.block_type = block_type
|
76
|
+
self.block_label = block_label
|
70
77
|
|
71
78
|
if self.children:
|
72
79
|
self.children[0].omit_prefix = False
|
@@ -186,12 +193,23 @@ class TranslatedCodeBlock(CodeBlock):
|
|
186
193
|
translated: Whether this block has been successfully translated
|
187
194
|
"""
|
188
195
|
|
189
|
-
def __init__(
|
196
|
+
def __init__(
|
197
|
+
self,
|
198
|
+
original: CodeBlock,
|
199
|
+
language: str,
|
200
|
+
converter: ForwardRef("Converter"),
|
201
|
+
block_type: str | None = None,
|
202
|
+
block_label: str | None = None,
|
203
|
+
) -> None:
|
190
204
|
"""Create an "empty" `TranslatedCodeBlock` from the given original
|
191
205
|
|
192
206
|
Arguments:
|
193
207
|
original: The original code block
|
194
208
|
language: The language to translate to
|
209
|
+
converter: the converter used to translate
|
210
|
+
block_type: type of the block
|
211
|
+
block_label: label for block
|
212
|
+
(for mapping outputs to inputs through ConverterChain)
|
195
213
|
|
196
214
|
Returns:
|
197
215
|
A `TranslatedCodeBlock` with the same attributes as the original, except
|
@@ -209,12 +227,17 @@ class TranslatedCodeBlock(CodeBlock):
|
|
209
227
|
end_byte=None,
|
210
228
|
tokens=0,
|
211
229
|
children=[
|
212
|
-
TranslatedCodeBlock(child, language
|
230
|
+
TranslatedCodeBlock(child, language, block_type, block_label)
|
231
|
+
for child in original.children
|
213
232
|
],
|
214
233
|
affixes=original.affixes,
|
215
234
|
previous_generations=original.previous_generations,
|
235
|
+
block_type=block_type,
|
236
|
+
block_label=block_label,
|
216
237
|
)
|
238
|
+
|
217
239
|
self.original = original
|
240
|
+
self.converter = converter
|
218
241
|
|
219
242
|
self.complete = original.complete
|
220
243
|
self.translated = False
|
@@ -279,6 +302,11 @@ class TranslatedCodeBlock(CodeBlock):
|
|
279
302
|
children_sum = sum(c.total_num_requests for c in self.children)
|
280
303
|
return children_sum + self.num_requests
|
281
304
|
|
305
|
+
@property
|
306
|
+
def total_processing_time(self) -> float:
|
307
|
+
children_sum = sum(c.total_processing_time for c in self.children)
|
308
|
+
return children_sum + self.processing_time
|
309
|
+
|
282
310
|
@property
|
283
311
|
def translation_completed(self) -> bool:
|
284
312
|
"""Whether or not the code block was successfully translated
|
@@ -317,6 +345,8 @@ class TranslatedCodeBlock(CodeBlock):
|
|
317
345
|
children=[child.to_codeblock() for child in self.children],
|
318
346
|
affixes=self.affixes,
|
319
347
|
previous_generations=self.previous_generations + [self],
|
348
|
+
block_type=self.block_type,
|
349
|
+
block_label=self.block_label,
|
320
350
|
)
|
321
351
|
|
322
352
|
def __iadd__(self, other):
|
@@ -326,3 +356,54 @@ class TranslatedCodeBlock(CodeBlock):
|
|
326
356
|
self.request_input_tokens += other.request_input_tokens
|
327
357
|
self.request_output_tokens += other.request_output_tokens
|
328
358
|
return self
|
359
|
+
|
360
|
+
|
361
|
+
class BlockCollection:
|
362
|
+
def __init__(
|
363
|
+
self,
|
364
|
+
blocks: list[CodeBlock],
|
365
|
+
previous_generations: list[ForwardRef("BlockCollection")] = [],
|
366
|
+
):
|
367
|
+
self.blocks = blocks
|
368
|
+
self.previous_generations = previous_generations
|
369
|
+
|
370
|
+
def to_codeblock(self) -> ForwardRef("BlockCollection"):
|
371
|
+
return BlockCollection(
|
372
|
+
[b.to_codeblock() for b in self.blocks], self.previous_generations + [self]
|
373
|
+
)
|
374
|
+
|
375
|
+
@property
|
376
|
+
def total_cost(self):
|
377
|
+
return sum(b.total_cost for b in self.blocks)
|
378
|
+
|
379
|
+
@property
|
380
|
+
def total_processing_time(self):
|
381
|
+
return sum(b.total_processing_time for b in self.blocks)
|
382
|
+
|
383
|
+
@property
|
384
|
+
def total_request_input_tokens(self):
|
385
|
+
return sum(b.total_request_input_tokens for b in self.blocks)
|
386
|
+
|
387
|
+
@property
|
388
|
+
def total_request_output_tokens(self):
|
389
|
+
return sum(b.total_request_output_tokens for b in self.blocks)
|
390
|
+
|
391
|
+
@property
|
392
|
+
def total_num_requests(self):
|
393
|
+
return sum(b.total_num_requests for b in self.blocks)
|
394
|
+
|
395
|
+
@property
|
396
|
+
def block_type(self):
|
397
|
+
return None
|
398
|
+
|
399
|
+
@property
|
400
|
+
def block_label(self):
|
401
|
+
return None
|
402
|
+
|
403
|
+
@property
|
404
|
+
def translation_completed(self):
|
405
|
+
return all(b.translation_completed for b in self.blocks)
|
406
|
+
|
407
|
+
@property
|
408
|
+
def complete(self):
|
409
|
+
return all(b.complete for b in self.blocks)
|
janus/llm/model_callbacks.py
CHANGED
@@ -44,12 +44,18 @@ COST_PER_1K_TOKENS: dict[str, dict[str, float]] = {
|
|
44
44
|
"anthropic.claude-instant-v1": {"input": 0.0008, "output": 0.0024},
|
45
45
|
"anthropic.claude-3-haiku-20240307-v1:0": {"input": 0.00025, "output": 0.00125},
|
46
46
|
"anthropic.claude-3-sonnet-20240229-v1:0": {"input": 0.003, "output": 0.015},
|
47
|
+
"anthropic.claude-3-5-sonnet-20240620-v1:0": {"input": 0.003, "output": 0.015},
|
48
|
+
"anthropic.claude-3-5-sonnet-20241022-v2:0": {"input": 0.003, "output": 0.015},
|
47
49
|
"meta.llama2-13b-chat-v1": {"input": 0.00075, "output": 0.001},
|
48
50
|
"meta.llama2-70b-chat-v1": {"input": 0.00195, "output": 0.00256},
|
49
51
|
"meta.llama2-13b-v1": {"input": 0.0, "output": 0.0},
|
50
52
|
"meta.llama2-70b-v1": {"input": 0.00265, "output": 0.0035},
|
51
53
|
"meta.llama3-8b-instruct-v1:0": {"input": 0.0003, "output": 0.0006},
|
52
54
|
"meta.llama3-70b-instruct-v1:0": {"input": 0.00265, "output": 0.0035},
|
55
|
+
"meta.llama3-3-70b-instruct-v1:0": {"input": 0.00072, "output": 0.00072},
|
56
|
+
"amazon.nova-lite-v1:0": {"input": 0.00006, "output": 0.00024},
|
57
|
+
"amazon.nova-micro-v1:0": {"input": 0.000035, "output": 0.00014},
|
58
|
+
"amazon.nova-pro-v1:0": {"input": 0.0008, "output": 0.0032},
|
53
59
|
"amazon.titan-text-lite-v1": {"input": 0.00015, "output": 0.0002},
|
54
60
|
"amazon.titan-text-express-v1": {"input": 0.0002, "output": 0.0006},
|
55
61
|
"ai21.j2-mid-v1": {"input": 0.0125, "output": 0.0125},
|