fabricatio 0.2.8.dev3__cp312-cp312-win_amd64.whl → 0.2.9__cp312-cp312-win_amd64.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.
- fabricatio/__init__.py +4 -11
- fabricatio/actions/__init__.py +1 -0
- fabricatio/actions/article.py +128 -165
- fabricatio/actions/article_rag.py +62 -46
- fabricatio/actions/output.py +60 -4
- fabricatio/actions/rag.py +2 -1
- fabricatio/actions/rules.py +72 -0
- fabricatio/capabilities/__init__.py +1 -0
- fabricatio/capabilities/censor.py +104 -0
- fabricatio/capabilities/check.py +148 -32
- fabricatio/capabilities/correct.py +162 -100
- fabricatio/capabilities/rag.py +5 -4
- fabricatio/capabilities/rating.py +109 -54
- fabricatio/capabilities/review.py +1 -1
- fabricatio/capabilities/task.py +2 -1
- fabricatio/config.py +14 -6
- fabricatio/fs/readers.py +20 -1
- fabricatio/models/action.py +63 -41
- fabricatio/models/adv_kwargs_types.py +25 -0
- fabricatio/models/extra/__init__.py +1 -0
- fabricatio/models/extra/advanced_judge.py +7 -4
- fabricatio/models/extra/article_base.py +125 -79
- fabricatio/models/extra/article_main.py +101 -19
- fabricatio/models/extra/article_outline.py +2 -3
- fabricatio/models/extra/article_proposal.py +15 -14
- fabricatio/models/extra/patches.py +20 -0
- fabricatio/models/extra/problem.py +64 -23
- fabricatio/models/extra/rule.py +39 -10
- fabricatio/models/generic.py +405 -75
- fabricatio/models/kwargs_types.py +23 -17
- fabricatio/models/task.py +1 -1
- fabricatio/models/tool.py +149 -14
- fabricatio/models/usages.py +55 -56
- fabricatio/parser.py +12 -13
- fabricatio/rust.cp312-win_amd64.pyd +0 -0
- fabricatio/{_rust.pyi → rust.pyi} +42 -4
- fabricatio/{_rust_instances.py → rust_instances.py} +1 -1
- fabricatio/utils.py +5 -5
- fabricatio/workflows/__init__.py +1 -0
- fabricatio/workflows/articles.py +3 -5
- fabricatio-0.2.9.data/scripts/tdown.exe +0 -0
- {fabricatio-0.2.8.dev3.dist-info → fabricatio-0.2.9.dist-info}/METADATA +1 -1
- fabricatio-0.2.9.dist-info/RECORD +61 -0
- fabricatio/_rust.cp312-win_amd64.pyd +0 -0
- fabricatio-0.2.8.dev3.data/scripts/tdown.exe +0 -0
- fabricatio-0.2.8.dev3.dist-info/RECORD +0 -53
- {fabricatio-0.2.8.dev3.dist-info → fabricatio-0.2.9.dist-info}/WHEEL +0 -0
- {fabricatio-0.2.8.dev3.dist-info → fabricatio-0.2.9.dist-info}/licenses/LICENSE +0 -0
@@ -1,160 +1,222 @@
|
|
1
|
-
"""Correct capability
|
1
|
+
"""A module containing the Correct capability for reviewing, validating, and improving objects."""
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
based on predefined criteria and templates.
|
6
|
-
"""
|
3
|
+
from asyncio import gather
|
4
|
+
from typing import Optional, Type, Unpack, cast
|
7
5
|
|
8
|
-
from
|
9
|
-
|
10
|
-
from fabricatio._rust_instances import TEMPLATE_MANAGER
|
11
|
-
from fabricatio.capabilities.review import Review
|
6
|
+
from fabricatio.capabilities.propose import Propose
|
7
|
+
from fabricatio.capabilities.rating import Rating
|
12
8
|
from fabricatio.config import configs
|
13
|
-
from fabricatio.
|
14
|
-
from fabricatio.models.
|
15
|
-
from fabricatio.models.
|
16
|
-
from fabricatio.models.
|
17
|
-
from
|
18
|
-
|
9
|
+
from fabricatio.journal import logger
|
10
|
+
from fabricatio.models.adv_kwargs_types import CorrectKwargs
|
11
|
+
from fabricatio.models.extra.problem import Improvement, ProblemSolutions
|
12
|
+
from fabricatio.models.generic import ProposedUpdateAble, SketchedAble
|
13
|
+
from fabricatio.models.kwargs_types import (
|
14
|
+
BestKwargs,
|
15
|
+
ValidateKwargs,
|
16
|
+
)
|
17
|
+
from fabricatio.rust_instances import TEMPLATE_MANAGER
|
18
|
+
from fabricatio.utils import fallback_kwargs, ok, override_kwargs
|
19
|
+
|
20
|
+
|
21
|
+
class Correct(Rating, Propose):
|
22
|
+
"""A class that provides the capability to correct objects."""
|
23
|
+
|
24
|
+
async def decide_solution(
|
25
|
+
self, problem_solutions: ProblemSolutions, **kwargs: Unpack[BestKwargs]
|
26
|
+
) -> ProblemSolutions:
|
27
|
+
"""Decide the best solution from a list of problem solutions.
|
28
|
+
|
29
|
+
Args:
|
30
|
+
problem_solutions (ProblemSolutions): The problem solutions to evaluate.
|
31
|
+
**kwargs (Unpack[BestKwargs]): Additional keyword arguments for the decision process.
|
19
32
|
|
33
|
+
Returns:
|
34
|
+
ProblemSolutions: The problem solutions with the best solution selected.
|
35
|
+
"""
|
36
|
+
if (leng := len(problem_solutions.solutions)) == 0:
|
37
|
+
logger.error(f"No solutions found in ProblemSolutions, Skip: `{problem_solutions.problem.name}`")
|
38
|
+
if leng > 1:
|
39
|
+
logger.info(f"{leng} solutions found in Problem `{problem_solutions.problem.name}`, select the best.")
|
40
|
+
problem_solutions.solutions = await self.best(problem_solutions.solutions, **kwargs)
|
41
|
+
return problem_solutions
|
20
42
|
|
21
|
-
|
22
|
-
|
43
|
+
async def decide_improvement(self, improvement: Improvement, **kwargs: Unpack[BestKwargs]) -> Improvement:
|
44
|
+
"""Decide the best solution for each problem solution in an improvement.
|
23
45
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
the required interfaces, applying corrections based on templated review processes.
|
28
|
-
"""
|
46
|
+
Args:
|
47
|
+
improvement (Improvement): The improvement containing problem solutions to evaluate.
|
48
|
+
**kwargs (Unpack[BestKwargs]): Additional keyword arguments for the decision process.
|
29
49
|
|
30
|
-
|
50
|
+
Returns:
|
51
|
+
Improvement: The improvement with the best solutions selected for each problem solution.
|
52
|
+
"""
|
53
|
+
if leng := len(improvement.problem_solutions):
|
54
|
+
logger.debug(f"{leng} problem_solutions found in Improvement, decide solution for each of them.")
|
55
|
+
await gather(
|
56
|
+
*[
|
57
|
+
self.decide_solution(
|
58
|
+
ps,
|
59
|
+
**fallback_kwargs(
|
60
|
+
kwargs, topic=f"which solution is better to deal this problem {ps.problem.description}\n\n"
|
61
|
+
),
|
62
|
+
)
|
63
|
+
for ps in improvement.problem_solutions
|
64
|
+
],
|
65
|
+
)
|
66
|
+
if any(not (violated := ps).decided() for ps in improvement.problem_solutions):
|
67
|
+
logger.error(f"Some problem_solutions are not decided: {violated}")
|
68
|
+
else:
|
69
|
+
logger.success(f"All problem_solutions are decided '{improvement.focused_on}'")
|
70
|
+
else:
|
71
|
+
logger.error(f"No problem_solutions found in Improvement, Skip: {improvement}")
|
72
|
+
return improvement
|
73
|
+
|
74
|
+
async def fix_troubled_obj[M: SketchedAble](
|
31
75
|
self,
|
32
76
|
obj: M,
|
77
|
+
problem_solutions: ProblemSolutions,
|
33
78
|
reference: str = "",
|
34
|
-
|
35
|
-
**kwargs: Unpack[ReviewKwargs[Improvement]],
|
79
|
+
**kwargs: Unpack[ValidateKwargs[M]],
|
36
80
|
) -> Optional[M]:
|
37
|
-
"""
|
38
|
-
|
39
|
-
This method first conducts a review of the given object, then uses the review results
|
40
|
-
to generate a corrected version of the object using appropriate templates.
|
81
|
+
"""Fix a troubled object based on problem solutions.
|
41
82
|
|
42
83
|
Args:
|
43
|
-
obj (M): The object to be
|
84
|
+
obj (M): The object to be fixed.
|
85
|
+
problem_solutions (ProblemSolutions): The problem solutions to apply.
|
44
86
|
reference (str): A reference or contextual information for the object.
|
45
|
-
|
46
|
-
**kwargs: Review configuration parameters including criteria and review options.
|
87
|
+
**kwargs (Unpack[ValidateKwargs[M]]): Additional keyword arguments for the validation process.
|
47
88
|
|
48
89
|
Returns:
|
49
|
-
Optional[M]:
|
50
|
-
|
51
|
-
Raises:
|
52
|
-
TypeError: If the provided object doesn't implement Display or WithBriefing interfaces.
|
90
|
+
Optional[M]: The fixed object, or None if fixing fails.
|
53
91
|
"""
|
54
|
-
if not isinstance(obj, (Display, WithBriefing)):
|
55
|
-
raise TypeError(f"Expected Display or WithBriefing, got {type(obj)}")
|
56
|
-
|
57
|
-
review_res = await self.review_obj(obj, **kwargs)
|
58
|
-
if supervisor_check:
|
59
|
-
await review_res.supervisor_check()
|
60
|
-
if "default" in kwargs:
|
61
|
-
cast("ReviewKwargs[None]", kwargs)["default"] = None
|
62
92
|
return await self.propose(
|
63
|
-
obj.__class__,
|
93
|
+
cast("Type[M]", obj.__class__),
|
64
94
|
TEMPLATE_MANAGER.render_template(
|
65
|
-
configs.templates.
|
95
|
+
configs.templates.fix_troubled_obj_template,
|
66
96
|
{
|
67
|
-
"
|
68
|
-
"
|
97
|
+
"problem": problem_solutions.problem.display(),
|
98
|
+
"solution": ok(
|
99
|
+
problem_solutions.final_solution(),
|
100
|
+
f"{len(problem_solutions.solutions)} solution Found for `{problem_solutions.problem.name}`.",
|
101
|
+
).display(),
|
102
|
+
"reference": reference,
|
69
103
|
},
|
70
104
|
),
|
71
105
|
**kwargs,
|
72
106
|
)
|
73
107
|
|
74
|
-
async def
|
75
|
-
self,
|
108
|
+
async def fix_troubled_string(
|
109
|
+
self,
|
110
|
+
input_text: str,
|
111
|
+
problem_solutions: ProblemSolutions,
|
112
|
+
reference: str = "",
|
113
|
+
**kwargs: Unpack[ValidateKwargs[str]],
|
76
114
|
) -> Optional[str]:
|
77
|
-
"""
|
78
|
-
|
79
|
-
This method applies the review process to the input text and generates
|
80
|
-
a corrected version based on the review results.
|
115
|
+
"""Fix a troubled string based on problem solutions.
|
81
116
|
|
82
117
|
Args:
|
83
|
-
input_text (str): The
|
84
|
-
|
85
|
-
|
118
|
+
input_text (str): The string to be fixed.
|
119
|
+
problem_solutions (ProblemSolutions): The problem solutions to apply.
|
120
|
+
reference (str): A reference or contextual information for the string.
|
121
|
+
**kwargs (Unpack[ValidateKwargs[str]]): Additional keyword arguments for the validation process.
|
86
122
|
|
87
123
|
Returns:
|
88
|
-
Optional[str]: The
|
124
|
+
Optional[str]: The fixed string, or None if fixing fails.
|
89
125
|
"""
|
90
|
-
review_res = await self.review_string(input_text, **kwargs)
|
91
|
-
if supervisor_check:
|
92
|
-
await review_res.supervisor_check()
|
93
|
-
|
94
|
-
if "default" in kwargs:
|
95
|
-
cast("ReviewKwargs[None]", kwargs)["default"] = None
|
96
126
|
return await self.ageneric_string(
|
97
127
|
TEMPLATE_MANAGER.render_template(
|
98
|
-
configs.templates.
|
128
|
+
configs.templates.fix_troubled_string_template,
|
129
|
+
{
|
130
|
+
"problem": problem_solutions.problem.display(),
|
131
|
+
"solution": ok(
|
132
|
+
problem_solutions.final_solution(),
|
133
|
+
f"No solution found for problem: {problem_solutions.problem}",
|
134
|
+
).display(),
|
135
|
+
"reference": reference,
|
136
|
+
"string_to_fix": input_text,
|
137
|
+
},
|
99
138
|
),
|
100
139
|
**kwargs,
|
101
140
|
)
|
102
141
|
|
103
|
-
async def
|
104
|
-
self,
|
105
|
-
|
106
|
-
|
142
|
+
async def correct_obj[M: SketchedAble](
|
143
|
+
self,
|
144
|
+
obj: M,
|
145
|
+
improvement: Improvement,
|
146
|
+
reference: str = "",
|
147
|
+
**kwargs: Unpack[ValidateKwargs[M]],
|
148
|
+
) -> Optional[M]:
|
149
|
+
"""Review and correct an object based on defined criteria and templates.
|
107
150
|
|
108
|
-
This
|
109
|
-
|
151
|
+
This method first conducts a review of the given object, then uses the review results
|
152
|
+
to generate a corrected version of the object using appropriate templates.
|
110
153
|
|
111
154
|
Args:
|
112
|
-
|
113
|
-
|
155
|
+
obj (M): The object to be reviewed and corrected. Must implement ProposedAble.
|
156
|
+
improvement (Improvement): The improvement object containing the review results.
|
157
|
+
reference (str): A reference or contextual information for the object.
|
158
|
+
**kwargs (Unpack[ValidateKwargs[M]]): Review configuration parameters including criteria and review options.
|
114
159
|
|
115
160
|
Returns:
|
116
|
-
Optional[
|
161
|
+
Optional[M]: A corrected version of the input object, or None if correction fails.
|
162
|
+
|
163
|
+
Raises:
|
164
|
+
TypeError: If the provided object doesn't implement Display or WithBriefing interfaces.
|
117
165
|
"""
|
118
|
-
|
166
|
+
if not improvement.decided():
|
167
|
+
logger.info(f"Improvement {improvement.focused_on} not decided, start deciding...")
|
168
|
+
improvement = await self.decide_improvement(improvement, **override_kwargs(kwargs, default=None))
|
169
|
+
|
170
|
+
total = len(improvement.problem_solutions)
|
171
|
+
for idx, ps in enumerate(improvement.problem_solutions):
|
172
|
+
logger.info(f"[{idx + 1}/{total}] Fixing {obj.__class__.__name__} for problem `{ps.problem.name}`")
|
173
|
+
fixed_obj = await self.fix_troubled_obj(obj, ps, reference, **kwargs)
|
174
|
+
if fixed_obj is None:
|
175
|
+
logger.error(f"[{idx + 1}/{total}] Failed to fix problem `{ps.problem.name}`")
|
176
|
+
return None
|
177
|
+
obj = fixed_obj
|
178
|
+
return obj
|
119
179
|
|
120
|
-
async def
|
121
|
-
self,
|
122
|
-
) ->
|
123
|
-
"""
|
180
|
+
async def correct_string(
|
181
|
+
self, input_text: str, improvement: Improvement, reference: str = "", **kwargs: Unpack[ValidateKwargs[str]]
|
182
|
+
) -> Optional[str]:
|
183
|
+
"""Review and correct a string based on defined criteria and templates.
|
184
|
+
|
185
|
+
This method first conducts a review of the given string, then uses the review results
|
186
|
+
to generate a corrected version of the string using appropriate templates.
|
124
187
|
|
125
188
|
Args:
|
126
|
-
|
127
|
-
|
189
|
+
input_text (str): The string to be reviewed and corrected.
|
190
|
+
improvement (Improvement): The improvement object containing the review results.
|
191
|
+
reference (str): A reference or contextual information for the string.
|
192
|
+
**kwargs (Unpack[ValidateKwargs[str]]): Review configuration parameters including criteria and review options.
|
128
193
|
|
129
194
|
Returns:
|
130
|
-
|
195
|
+
Optional[str]: A corrected version of the input string, or None if correction fails.
|
131
196
|
"""
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
**kwargs,
|
197
|
+
if not improvement.decided():
|
198
|
+
logger.info(f"Improvement {improvement.focused_on} not decided, start deciding...")
|
199
|
+
|
200
|
+
improvement = await self.decide_improvement(improvement, **override_kwargs(kwargs, default=None))
|
201
|
+
|
202
|
+
for ps in improvement.problem_solutions:
|
203
|
+
fixed_string = await self.fix_troubled_string(input_text, ps, reference, **kwargs)
|
204
|
+
if fixed_string is None:
|
205
|
+
logger.error(
|
206
|
+
f"Failed to fix troubling string when deal with problem: {ps.problem}",
|
143
207
|
)
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
rprint(last_modified_obj.finalized_dump())
|
148
|
-
return modified_obj or last_modified_obj
|
208
|
+
return None
|
209
|
+
input_text = fixed_string
|
210
|
+
return input_text
|
149
211
|
|
150
212
|
async def correct_obj_inplace[M: ProposedUpdateAble](
|
151
|
-
self, obj: M, **kwargs: Unpack[CorrectKwargs[
|
213
|
+
self, obj: M, **kwargs: Unpack[CorrectKwargs[M]]
|
152
214
|
) -> Optional[M]:
|
153
215
|
"""Correct an object in place based on defined criteria and templates.
|
154
216
|
|
155
217
|
Args:
|
156
218
|
obj (M): The object to be corrected.
|
157
|
-
**kwargs (Unpack[
|
219
|
+
**kwargs (Unpack[CorrectKwargs[M]]): Additional keyword arguments for the correction process.
|
158
220
|
|
159
221
|
Returns:
|
160
222
|
Optional[M]: The corrected object, or None if correction fails.
|
fabricatio/capabilities/rag.py
CHANGED
@@ -3,14 +3,16 @@
|
|
3
3
|
try:
|
4
4
|
from pymilvus import MilvusClient
|
5
5
|
except ImportError as e:
|
6
|
-
raise RuntimeError("pymilvus is not installed. Have you installed `fabricatio[rag]` instead of `fabricatio
|
6
|
+
raise RuntimeError("pymilvus is not installed. Have you installed `fabricatio[rag]` instead of `fabricatio`?") from e
|
7
7
|
from functools import lru_cache
|
8
8
|
from operator import itemgetter
|
9
9
|
from os import PathLike
|
10
10
|
from pathlib import Path
|
11
11
|
from typing import Any, Callable, Dict, List, Optional, Self, Union, Unpack, cast, overload
|
12
12
|
|
13
|
-
from
|
13
|
+
from more_itertools.recipes import flatten, unique
|
14
|
+
from pydantic import Field, PrivateAttr
|
15
|
+
|
14
16
|
from fabricatio.config import configs
|
15
17
|
from fabricatio.journal import logger
|
16
18
|
from fabricatio.models.kwargs_types import (
|
@@ -23,9 +25,8 @@ from fabricatio.models.kwargs_types import (
|
|
23
25
|
)
|
24
26
|
from fabricatio.models.usages import EmbeddingUsage
|
25
27
|
from fabricatio.models.utils import MilvusData
|
28
|
+
from fabricatio.rust_instances import TEMPLATE_MANAGER
|
26
29
|
from fabricatio.utils import ok
|
27
|
-
from more_itertools.recipes import flatten, unique
|
28
|
-
from pydantic import Field, PrivateAttr
|
29
30
|
|
30
31
|
|
31
32
|
@lru_cache(maxsize=None)
|
@@ -4,18 +4,20 @@ from itertools import permutations
|
|
4
4
|
from random import sample
|
5
5
|
from typing import Dict, List, Optional, Set, Tuple, Union, Unpack, overload
|
6
6
|
|
7
|
-
from
|
7
|
+
from more_itertools import flatten, windowed
|
8
|
+
from pydantic import Field, NonNegativeInt, PositiveInt, create_model
|
9
|
+
|
10
|
+
from fabricatio.capabilities.propose import Propose
|
8
11
|
from fabricatio.config import configs
|
9
12
|
from fabricatio.journal import logger
|
10
|
-
from fabricatio.models.
|
11
|
-
from fabricatio.models.
|
13
|
+
from fabricatio.models.generic import Display, ProposedAble
|
14
|
+
from fabricatio.models.kwargs_types import CompositeScoreKwargs, ValidateKwargs
|
12
15
|
from fabricatio.parser import JsonCapture
|
13
|
-
from fabricatio.
|
14
|
-
from
|
15
|
-
from pydantic import NonNegativeInt, PositiveInt
|
16
|
+
from fabricatio.rust_instances import TEMPLATE_MANAGER
|
17
|
+
from fabricatio.utils import fallback_kwargs, ok, override_kwargs
|
16
18
|
|
17
19
|
|
18
|
-
class Rating(
|
20
|
+
class Rating(Propose):
|
19
21
|
"""A class that provides functionality to rate tasks based on a rating manual and score range.
|
20
22
|
|
21
23
|
References:
|
@@ -28,7 +30,7 @@ class Rating(LLMUsage):
|
|
28
30
|
rating_manual: Dict[str, str],
|
29
31
|
score_range: Tuple[float, float],
|
30
32
|
**kwargs: Unpack[ValidateKwargs[Dict[str, float]]],
|
31
|
-
) ->
|
33
|
+
) -> Dict[str, float] | List[Dict[str, float]] | List[Optional[Dict[str, float]]] | None:
|
32
34
|
"""Rate a given string based on a rating manual and score range.
|
33
35
|
|
34
36
|
Args:
|
@@ -40,45 +42,49 @@ class Rating(LLMUsage):
|
|
40
42
|
Returns:
|
41
43
|
Dict[str, float]: A dictionary with the ratings for each dimension.
|
42
44
|
"""
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
"to_rate": to_rate,
|
60
|
-
"min_score": score_range[0],
|
61
|
-
"max_score": score_range[1],
|
62
|
-
"rating_manual": rating_manual,
|
63
|
-
},
|
45
|
+
min_score, max_score = score_range
|
46
|
+
tip = (max_score - min_score) / 9
|
47
|
+
|
48
|
+
model = create_model( # pyright: ignore [reportCallIssue]
|
49
|
+
"RatingResult",
|
50
|
+
__base__=ProposedAble,
|
51
|
+
__doc__=f"The rating result contains the scores against each criterion, with min_score={min_score} and max_score={max_score}.",
|
52
|
+
**{ # pyright: ignore [reportArgumentType]
|
53
|
+
criterion: (
|
54
|
+
float,
|
55
|
+
Field(
|
56
|
+
ge=min_score,
|
57
|
+
le=max_score,
|
58
|
+
description=desc,
|
59
|
+
examples=[round(min_score + tip * i, 2) for i in range(10)],
|
60
|
+
),
|
64
61
|
)
|
62
|
+
for criterion, desc in rating_manual.items()
|
63
|
+
},
|
64
|
+
)
|
65
|
+
|
66
|
+
res = await self.propose(
|
67
|
+
model,
|
68
|
+
TEMPLATE_MANAGER.render_template(
|
69
|
+
configs.templates.rate_fine_grind_template,
|
70
|
+
{"to_rate": to_rate, "min_score": min_score, "max_score": max_score},
|
65
71
|
)
|
66
72
|
if isinstance(to_rate, str)
|
67
73
|
else [
|
68
74
|
TEMPLATE_MANAGER.render_template(
|
69
75
|
configs.templates.rate_fine_grind_template,
|
70
|
-
{
|
71
|
-
"to_rate": item,
|
72
|
-
"min_score": score_range[0],
|
73
|
-
"max_score": score_range[1],
|
74
|
-
"rating_manual": rating_manual,
|
75
|
-
},
|
76
|
+
{"to_rate": t, "min_score": min_score, "max_score": max_score},
|
76
77
|
)
|
77
|
-
for
|
78
|
+
for t in to_rate
|
78
79
|
],
|
79
|
-
|
80
|
-
**kwargs,
|
80
|
+
**override_kwargs(kwargs, default=None),
|
81
81
|
)
|
82
|
+
default = kwargs.get("default")
|
83
|
+
if isinstance(res, list):
|
84
|
+
return [r.model_dump() if r else default for r in res]
|
85
|
+
if res is None:
|
86
|
+
return default
|
87
|
+
return res.model_dump()
|
82
88
|
|
83
89
|
@overload
|
84
90
|
async def rate(
|
@@ -86,6 +92,7 @@ class Rating(LLMUsage):
|
|
86
92
|
to_rate: str,
|
87
93
|
topic: str,
|
88
94
|
criteria: Set[str],
|
95
|
+
manual: Optional[Dict[str, str]] = None,
|
89
96
|
score_range: Tuple[float, float] = (0.0, 1.0),
|
90
97
|
**kwargs: Unpack[ValidateKwargs],
|
91
98
|
) -> Dict[str, float]: ...
|
@@ -96,6 +103,7 @@ class Rating(LLMUsage):
|
|
96
103
|
to_rate: List[str],
|
97
104
|
topic: str,
|
98
105
|
criteria: Set[str],
|
106
|
+
manual: Optional[Dict[str, str]] = None,
|
99
107
|
score_range: Tuple[float, float] = (0.0, 1.0),
|
100
108
|
**kwargs: Unpack[ValidateKwargs],
|
101
109
|
) -> List[Dict[str, float]]: ...
|
@@ -105,15 +113,17 @@ class Rating(LLMUsage):
|
|
105
113
|
to_rate: Union[str, List[str]],
|
106
114
|
topic: str,
|
107
115
|
criteria: Set[str],
|
116
|
+
manual: Optional[Dict[str, str]] = None,
|
108
117
|
score_range: Tuple[float, float] = (0.0, 1.0),
|
109
118
|
**kwargs: Unpack[ValidateKwargs],
|
110
|
-
) ->
|
119
|
+
) -> Dict[str, float] | List[Dict[str, float]] | List[Optional[Dict[str, float]]] | None:
|
111
120
|
"""Rate a given string or a sequence of strings based on a topic, criteria, and score range.
|
112
121
|
|
113
122
|
Args:
|
114
123
|
to_rate (Union[str, List[str]]): The string or sequence of strings to be rated.
|
115
124
|
topic (str): The topic related to the task.
|
116
125
|
criteria (Set[str]): A set of criteria for rating.
|
126
|
+
manual (Optional[Dict[str, str]]): A dictionary containing the rating criteria. If not provided, then this method will draft the criteria automatically.
|
117
127
|
score_range (Tuple[float, float], optional): A tuple representing the valid score range. Defaults to (0.0, 1.0).
|
118
128
|
**kwargs (Unpack[ValidateKwargs]): Additional keyword arguments for the LLM usage.
|
119
129
|
|
@@ -121,9 +131,13 @@ class Rating(LLMUsage):
|
|
121
131
|
Union[Dict[str, float], List[Dict[str, float]]]: A dictionary with the ratings for each criterion if a single string is provided,
|
122
132
|
or a list of dictionaries with the ratings for each criterion if a sequence of strings is provided.
|
123
133
|
"""
|
124
|
-
manual =
|
134
|
+
manual = (
|
135
|
+
manual
|
136
|
+
or await self.draft_rating_manual(topic, criteria, **override_kwargs(kwargs, default=None))
|
137
|
+
or dict(zip(criteria, criteria, strict=True))
|
138
|
+
)
|
125
139
|
|
126
|
-
return await self.rate_fine_grind(to_rate, manual, score_range, **kwargs)
|
140
|
+
return await self.rate_fine_grind(to_rate, manual, score_range, **fallback_kwargs(kwargs, co_extractor={}))
|
127
141
|
|
128
142
|
async def draft_rating_manual(
|
129
143
|
self, topic: str, criteria: Optional[Set[str]] = None, **kwargs: Unpack[ValidateKwargs[Dict[str, str]]]
|
@@ -160,7 +174,7 @@ class Rating(LLMUsage):
|
|
160
174
|
configs.templates.draft_rating_manual_template,
|
161
175
|
{
|
162
176
|
"topic": topic,
|
163
|
-
"criteria": criteria,
|
177
|
+
"criteria": list(criteria),
|
164
178
|
},
|
165
179
|
)
|
166
180
|
),
|
@@ -234,7 +248,7 @@ class Rating(LLMUsage):
|
|
234
248
|
|
235
249
|
# extract reasons from the comparison of ordered pairs of extracted from examples
|
236
250
|
reasons = flatten(
|
237
|
-
await self.aask_validate(
|
251
|
+
await self.aask_validate( # pyright: ignore [reportArgumentType]
|
238
252
|
question=[
|
239
253
|
TEMPLATE_MANAGER.render_template(
|
240
254
|
configs.templates.extract_reasons_from_examples_template,
|
@@ -309,9 +323,11 @@ class Rating(LLMUsage):
|
|
309
323
|
validator=lambda resp: JsonCapture.validate_with(resp, target_type=float),
|
310
324
|
**kwargs,
|
311
325
|
)
|
312
|
-
|
326
|
+
if not all(relative_weights):
|
327
|
+
raise ValueError(f"found illegal weight: {relative_weights}")
|
328
|
+
weights = [1.0]
|
313
329
|
for rw in relative_weights:
|
314
|
-
weights.append(weights[-1] * rw)
|
330
|
+
weights.append(weights[-1] * rw) # pyright: ignore [reportOperatorIssue]
|
315
331
|
total = sum(weights)
|
316
332
|
return dict(zip(criteria_seq, [w / total for w in weights], strict=True))
|
317
333
|
|
@@ -319,27 +335,66 @@ class Rating(LLMUsage):
|
|
319
335
|
self,
|
320
336
|
topic: str,
|
321
337
|
to_rate: List[str],
|
322
|
-
|
323
|
-
|
324
|
-
|
338
|
+
criteria: Optional[Set[str]] = None,
|
339
|
+
weights: Optional[Dict[str, float]] = None,
|
340
|
+
manual: Optional[Dict[str, str]] = None,
|
341
|
+
**kwargs: Unpack[ValidateKwargs[List[Dict[str, float]]]],
|
325
342
|
) -> List[float]:
|
326
343
|
"""Calculates the composite scores for a list of items based on a given topic and criteria.
|
327
344
|
|
328
345
|
Args:
|
329
346
|
topic (str): The topic for the rating.
|
330
347
|
to_rate (List[str]): A list of strings to be rated.
|
331
|
-
|
332
|
-
|
348
|
+
criteria (Optional[Set[str]]): A set of criteria for the rating. Defaults to None.
|
349
|
+
weights (Optional[Dict[str, float]]): A dictionary of rating weights for each criterion. Defaults to None.
|
350
|
+
manual (Optional[Dict[str, str]]): A dictionary of manual ratings for each item. Defaults to None.
|
333
351
|
**kwargs (Unpack[ValidateKwargs]): Additional keyword arguments for the LLM usage.
|
334
352
|
|
335
353
|
Returns:
|
336
354
|
List[float]: A list of composite scores for the items.
|
337
355
|
"""
|
338
|
-
criteria =
|
339
|
-
|
356
|
+
criteria = ok(
|
357
|
+
criteria
|
358
|
+
or await self.draft_rating_criteria_from_examples(topic, to_rate, **override_kwargs(kwargs, default=None))
|
359
|
+
)
|
360
|
+
weights = ok(
|
361
|
+
weights or await self.drafting_rating_weights_klee(topic, criteria, **override_kwargs(kwargs, default=None))
|
340
362
|
)
|
341
|
-
weights = await self.drafting_rating_weights_klee(topic, criteria, **kwargs)
|
342
363
|
logger.info(f"Criteria: {criteria}\nWeights: {weights}")
|
343
|
-
ratings_seq = await self.rate(to_rate, topic, criteria, **kwargs)
|
364
|
+
ratings_seq = await self.rate(to_rate, topic, criteria, manual, **kwargs)
|
344
365
|
|
345
366
|
return [sum(ratings[c] * weights[c] for c in criteria) for ratings in ratings_seq]
|
367
|
+
|
368
|
+
@overload
|
369
|
+
async def best(self, candidates: List[str], k: int = 1, **kwargs: Unpack[CompositeScoreKwargs]) -> List[str]: ...
|
370
|
+
@overload
|
371
|
+
async def best[T: Display](
|
372
|
+
self, candidates: List[T], k: int = 1, **kwargs: Unpack[CompositeScoreKwargs]
|
373
|
+
) -> List[T]: ...
|
374
|
+
|
375
|
+
async def best[T: Display](
|
376
|
+
self, candidates: List[str] | List[T], k: int = 1, **kwargs: Unpack[CompositeScoreKwargs]
|
377
|
+
) -> Optional[List[str] | List[T]]:
|
378
|
+
"""Choose the best candidates from the list of candidates based on the composite score.
|
379
|
+
|
380
|
+
Args:
|
381
|
+
k (int): The number of best candidates to choose.
|
382
|
+
candidates (List[str]): A list of candidates to choose from.
|
383
|
+
**kwargs (CompositeScoreKwargs): Additional keyword arguments for the composite score calculation.
|
384
|
+
|
385
|
+
Returns:
|
386
|
+
List[str]: The best candidates.
|
387
|
+
"""
|
388
|
+
if (leng := len(candidates)) == 0:
|
389
|
+
logger.warning(f"No candidates, got {leng}, return None.")
|
390
|
+
return None
|
391
|
+
|
392
|
+
if leng == 1:
|
393
|
+
logger.warning(f"Only one candidate, got {leng}, return it.")
|
394
|
+
return candidates
|
395
|
+
logger.info(f"Choose best {k} from {leng} candidates.")
|
396
|
+
|
397
|
+
rating_seq = await self.composite_score(
|
398
|
+
to_rate=[c.display() if isinstance(c, Display) else c for c in candidates], **kwargs
|
399
|
+
)
|
400
|
+
return [a[0] for a in sorted(zip(candidates, rating_seq, strict=True), key=lambda x: x[1], reverse=True)[:k]] # pyright: ignore [reportReturnType]
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
from typing import Dict, Optional, Set, Unpack
|
4
4
|
|
5
|
-
from fabricatio._rust_instances import TEMPLATE_MANAGER
|
6
5
|
from fabricatio.capabilities.propose import Propose
|
7
6
|
from fabricatio.capabilities.rating import Rating
|
8
7
|
from fabricatio.config import configs
|
@@ -10,6 +9,7 @@ from fabricatio.models.extra.problem import Improvement
|
|
10
9
|
from fabricatio.models.generic import Display, WithBriefing
|
11
10
|
from fabricatio.models.kwargs_types import ReviewKwargs, ValidateKwargs
|
12
11
|
from fabricatio.models.task import Task
|
12
|
+
from fabricatio.rust_instances import TEMPLATE_MANAGER
|
13
13
|
from fabricatio.utils import ok
|
14
14
|
|
15
15
|
|