fabricatio 0.2.8.dev2__cp312-cp312-win_amd64.whl → 0.2.8.dev3__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/_rust.cp312-win_amd64.pyd +0 -0
- fabricatio/_rust.pyi +1 -1
- fabricatio/actions/article.py +72 -56
- fabricatio/actions/article_rag.py +4 -5
- fabricatio/actions/output.py +4 -3
- fabricatio/actions/rag.py +3 -3
- fabricatio/capabilities/check.py +97 -0
- fabricatio/capabilities/correct.py +7 -6
- fabricatio/capabilities/propose.py +20 -4
- fabricatio/capabilities/rag.py +3 -2
- fabricatio/capabilities/rating.py +7 -10
- fabricatio/capabilities/review.py +18 -187
- fabricatio/capabilities/task.py +8 -9
- fabricatio/config.py +2 -0
- fabricatio/models/action.py +6 -2
- fabricatio/models/extra/advanced_judge.py +7 -7
- fabricatio/models/extra/article_base.py +45 -8
- fabricatio/models/extra/article_essence.py +40 -209
- fabricatio/models/extra/article_main.py +1 -1
- fabricatio/models/extra/problem.py +120 -0
- fabricatio/models/extra/rule.py +23 -0
- fabricatio/models/generic.py +28 -33
- fabricatio/models/role.py +4 -1
- fabricatio/models/usages.py +8 -6
- fabricatio/models/utils.py +0 -46
- fabricatio/utils.py +54 -0
- {fabricatio-0.2.8.dev2.data → fabricatio-0.2.8.dev3.data}/scripts/tdown.exe +0 -0
- {fabricatio-0.2.8.dev2.dist-info → fabricatio-0.2.8.dev3.dist-info}/METADATA +2 -1
- fabricatio-0.2.8.dev3.dist-info/RECORD +53 -0
- fabricatio-0.2.8.dev2.dist-info/RECORD +0 -49
- {fabricatio-0.2.8.dev2.dist-info → fabricatio-0.2.8.dev3.dist-info}/WHEEL +0 -0
- {fabricatio-0.2.8.dev2.dist-info → fabricatio-0.2.8.dev3.dist-info}/licenses/LICENSE +0 -0
@@ -2,267 +2,98 @@
|
|
2
2
|
|
3
3
|
from typing import List, Self
|
4
4
|
|
5
|
-
from fabricatio.models.generic import Display, PersistentAble,
|
6
|
-
from pydantic import BaseModel
|
5
|
+
from fabricatio.models.generic import Display, PersistentAble, ProposedAble, Vectorizable
|
6
|
+
from pydantic import BaseModel
|
7
7
|
|
8
8
|
|
9
9
|
class Equation(BaseModel):
|
10
|
-
"""Mathematical formalism specification for research contributions.
|
11
|
-
|
12
|
-
Encodes equations with dual representation: semantic meaning and typeset-ready notation.
|
13
|
-
"""
|
10
|
+
"""Mathematical formalism specification for research contributions."""
|
14
11
|
|
15
12
|
description: str
|
16
|
-
"""
|
17
|
-
1.
|
18
|
-
2.
|
19
|
-
3.
|
20
|
-
Example: "Defines constrained search space dimensionality reduction. Used in architecture optimization phase (Section 3.2). Enables 40% parameter reduction."
|
13
|
+
"""Structured significance including:
|
14
|
+
1. Conceptual meaning
|
15
|
+
2. Technical workflow role
|
16
|
+
3. Contribution relationship
|
21
17
|
"""
|
22
18
|
|
23
|
-
|
24
|
-
|
25
|
-
#let x = 5 // Define a code variable
|
26
|
-
|
27
|
-
// Basic syntax examples
|
28
|
-
$x^2$ // Inline formula
|
29
|
-
$ x^2 $ // Block formula (spaces before/after $ for standalone display)
|
30
|
-
|
31
|
-
// Variables and text handling
|
32
|
-
$ A = pi r^2 $ // Single-letter variables as-is
|
33
|
-
$"area" = pi dot "radius"^2 $ // Multi-letter variables in quotes
|
34
|
-
$ cal(A) := { x in RR | x "is natural" } $ // Calligraphic font and text
|
35
|
-
$ #x < 17 $ // Access code variables with #
|
36
|
-
|
37
|
-
// Symbols and shorthands
|
38
|
-
$x < y => x gt.eq.not y $ // Symbol shorthand (=> for ⇒, gt.eq.not for ≯)
|
39
|
-
|
40
|
-
// Multi-line equations with alignment
|
41
|
-
$ sum_(k=0)^n k
|
42
|
-
&= 1 + ... + n \
|
43
|
-
&= (n(n+1))/2 $ // Multi-line with & alignment
|
44
|
-
|
45
|
-
// Function calls and formatting
|
46
|
-
$ frac(a^2, 2) $ // Fraction
|
47
|
-
$ vec(1, 2, delim: "[") $ // Custom vector delimiter
|
48
|
-
$ mat(1, 2; 3, 4) $ // 2D matrix (semicolon separates rows)
|
49
|
-
$ mat(..#range(1, 5).chunks(2)) $ // Dynamic matrix with array expansion
|
50
|
-
|
51
|
-
// Advanced alignment example
|
52
|
-
$ (3x + y)/7 &= 9 && "given" \
|
53
|
-
3x + y &= 63 & "multiply by 7" \
|
54
|
-
3x &= 63 - y && "subtract y" \
|
55
|
-
x &= 21 - y/3 & "divide by 3" $
|
56
|
-
// && skips a column alignment (left/right alternation)
|
57
|
-
|
58
|
-
// Math font configuration
|
59
|
-
#show math.equation: set text(font: "Fira Math") // Set math font (requires Fira Math installed)
|
60
|
-
$ sum_(i in NN) 1 + i $ // Display with new font
|
61
|
-
|
62
|
-
// Escaping and special syntax
|
63
|
-
$ frac(a\,, b) $ // Escape comma to display as literal
|
64
|
-
$ f(x; y) $ // Literal semicolon (not for 2D arrays)
|
65
|
-
$ lim_x = op("lim", limits: #true)_x $ // Custom operator with limits
|
66
|
-
"""
|
19
|
+
latex_code: str
|
20
|
+
"""Typeset-ready notation."""
|
67
21
|
|
68
22
|
|
69
23
|
class Figure(BaseModel):
|
70
|
-
"""Visual component
|
71
|
-
|
72
|
-
Combines graphical assets with structured academic captioning.Extracted from the article provided
|
73
|
-
"""
|
24
|
+
"""Visual component with academic captioning."""
|
74
25
|
|
75
26
|
description: str
|
76
|
-
"""
|
77
|
-
1.
|
78
|
-
2. Data representation
|
79
|
-
3.
|
80
|
-
Example: "Architecture search space topology (left) vs. convergence curves (right). Demonstrates NAS efficiency gains through constrained search."
|
27
|
+
"""Interpretation guide covering:
|
28
|
+
1. Visual element mapping
|
29
|
+
2. Data representation method
|
30
|
+
3. Research connection
|
81
31
|
"""
|
82
32
|
|
83
33
|
figure_caption: str
|
84
|
-
"""
|
85
|
-
1.
|
86
|
-
2. Technical
|
87
|
-
3. Result
|
88
|
-
Example: "Figure 3: Differentiable NAS framework. (a) Search space topology with constrained dimensions. (b) Training convergence across language pairs. Dashed lines indicate baseline methods."
|
34
|
+
"""Nature-style caption containing:
|
35
|
+
1. Overview statement
|
36
|
+
2. Technical details
|
37
|
+
3. Result implications
|
89
38
|
"""
|
90
39
|
|
91
40
|
figure_serial_number: int
|
92
|
-
"""
|
93
|
-
|
94
|
-
|
95
|
-
class Algorithm(BaseModel):
|
96
|
-
"""Algorithm specification for research contributions."""
|
97
|
-
|
98
|
-
title: str
|
99
|
-
"""Algorithm title with technical focus descriptor (e.g., 'Gradient Descent Optimization').
|
100
|
-
|
101
|
-
Tip: Do not attempt to translate the original element titles when generating JSON.
|
102
|
-
"""
|
103
|
-
|
104
|
-
description: str
|
105
|
-
"""Algorithm description with technical focus descriptor:
|
106
|
-
- Includes input/output specifications.
|
107
|
-
- Describes key steps and their purpose.
|
108
|
-
- Explains its role in the research workflow.
|
109
|
-
Example: "Proposed algorithm for neural architecture search. Inputs include search space constraints and training data. Outputs optimized architecture."
|
110
|
-
"""
|
111
|
-
|
112
|
-
|
113
|
-
class Table(BaseModel):
|
114
|
-
"""Table specification for research contributions."""
|
115
|
-
|
116
|
-
title: str
|
117
|
-
"""Table title with technical focus descriptor (e.g., 'Comparison of Model Performance Metrics').
|
118
|
-
|
119
|
-
Tip: Do not attempt to translate the original element titles when generating JSON.
|
120
|
-
"""
|
121
|
-
|
122
|
-
description: str
|
123
|
-
"""Table description with technical focus descriptor:
|
124
|
-
- Includes data source and structure.
|
125
|
-
- Explains key columns/rows and their significance.
|
126
|
-
- Connects to research findings or hypotheses.
|
127
|
-
Example: "Performance metrics for different architectures. Columns represent accuracy, F1-score, and inference time. Highlights efficiency gains of proposed method."
|
128
|
-
"""
|
41
|
+
"""Image serial number extracted from Markdown path"""
|
129
42
|
|
130
43
|
|
131
44
|
class Highlightings(BaseModel):
|
132
|
-
"""Technical
|
133
|
-
|
134
|
-
Curates core scientific components with machine-parseable annotations.
|
135
|
-
"""
|
45
|
+
"""Technical component aggregator."""
|
136
46
|
|
137
47
|
highlighted_equations: List[Equation]
|
138
|
-
"""
|
139
|
-
- Each equation must be wrapped in $$ for display math.
|
140
|
-
- Contain at least one novel operator/symbol.
|
141
|
-
- Be referenced in Methods/Results sections.
|
142
|
-
Example: Equation describing proposed loss function.
|
143
|
-
"""
|
144
|
-
|
145
|
-
highlighted_algorithms: List[Algorithm]
|
146
|
-
"""1-2 key algorithms demonstrating methodological contributions:
|
147
|
-
- Include pseudocode or step-by-step descriptions.
|
148
|
-
- Highlight innovation in computational approach.
|
149
|
-
Example: Algorithm for constrained search space exploration.
|
150
|
-
|
151
|
-
Tip: Do not attempt to translate the original element titles when generating JSON.
|
152
|
-
"""
|
48
|
+
"""Equations that highlight the article's core contributions"""
|
153
49
|
|
154
50
|
highlighted_figures: List[Figure]
|
155
|
-
"""
|
156
|
-
1. Framework overview
|
157
|
-
2. Quantitative results
|
158
|
-
3. Ablation studies (1 optional).
|
159
|
-
Each must appear in Results/Discussion chapters.
|
160
|
-
Example: Figure showing architecture topology and convergence curves.
|
161
|
-
"""
|
162
|
-
|
163
|
-
highlighted_tables: List[Table]
|
164
|
-
"""2-3 key tables summarizing:
|
165
|
-
- Comparative analysis of methods.
|
166
|
-
- Empirical results supporting claims.
|
167
|
-
Example: Table comparing model performance across datasets.
|
168
|
-
|
169
|
-
Tip: Do not attempt to translate the original element titles when generating JSON.
|
51
|
+
"""key figures requiring:
|
52
|
+
1. Framework overview
|
53
|
+
2. Quantitative results
|
170
54
|
"""
|
171
55
|
|
172
56
|
|
173
|
-
class ArticleEssence(ProposedAble, Display, PersistentAble,
|
174
|
-
"""
|
57
|
+
class ArticleEssence(ProposedAble, Display, PersistentAble, Vectorizable):
|
58
|
+
"""Structured representation of a scientific article's core elements in its original language."""
|
175
59
|
|
176
60
|
language: str
|
177
|
-
"""Language of the original article
|
61
|
+
"""Language of the original article."""
|
178
62
|
|
179
|
-
title: str
|
180
|
-
"""Exact title of the original article
|
181
|
-
Must be preserved precisely from the source material without:
|
182
|
-
- Translation
|
183
|
-
- Paraphrasing
|
184
|
-
- Adding/removing words
|
185
|
-
- Altering style or formatting
|
186
|
-
"""
|
63
|
+
title: str
|
64
|
+
"""Exact title of the original article."""
|
187
65
|
|
188
66
|
authors: List[str]
|
189
|
-
"""Original author full names
|
190
|
-
Extract complete list without any modifications or formatting changes."""
|
67
|
+
"""Original author full names as they appear in the source document."""
|
191
68
|
|
192
69
|
keywords: List[str]
|
193
|
-
"""Original keywords
|
194
|
-
Extract the complete set without modifying format or terminology."""
|
70
|
+
"""Original keywords as they appear in the source document."""
|
195
71
|
|
196
72
|
publication_year: int
|
197
|
-
"""Publication
|
73
|
+
"""Publication year in ISO 8601 (YYYY format)."""
|
198
74
|
|
199
75
|
highlightings: Highlightings
|
200
|
-
"""Technical
|
201
|
-
- Core equations (Theory)
|
202
|
-
- Key algorithms (Implementation)
|
203
|
-
- Critical figures (Results)
|
204
|
-
- Benchmark tables (Evaluation)"""
|
76
|
+
"""Technical highlights including equations, algorithms, figures, and tables."""
|
205
77
|
|
206
|
-
|
207
|
-
"""
|
208
|
-
|
209
|
-
abstract: str = Field(...)
|
210
|
-
"""Abstract text with original language."""
|
78
|
+
abstract: str
|
79
|
+
"""Abstract text in the original language."""
|
211
80
|
|
212
81
|
core_contributions: List[str]
|
213
|
-
"""
|
214
|
-
Each item starts with action verb.
|
215
|
-
Example:
|
216
|
-
- 'Developed constrained NAS framework'
|
217
|
-
- 'Established cross-lingual transfer metrics'"""
|
82
|
+
"""Technical contributions using CRediT taxonomy verbs."""
|
218
83
|
|
219
84
|
technical_novelty: List[str]
|
220
|
-
|
221
|
-
"""Patent-style claims with technical specificity.
|
222
|
-
Format: 'A [system/method] comprising [novel components]...'
|
223
|
-
Example:
|
224
|
-
'A neural architecture search system comprising:
|
225
|
-
a differentiable constrained search space;
|
226
|
-
multi-lingual transferability predictors...'"""
|
85
|
+
"""Patent-style claims with technical specificity."""
|
227
86
|
|
228
87
|
research_problems: List[str]
|
229
|
-
"""Problem statements as how/why questions.
|
230
|
-
Example:
|
231
|
-
- 'How to reduce NAS computational overhead while maintaining search diversity?'
|
232
|
-
- 'Why do existing architectures fail in low-resource cross-lingual transfer?'"""
|
88
|
+
"""Problem statements as how/why questions."""
|
233
89
|
|
234
90
|
limitations: List[str]
|
235
|
-
"""Technical limitations analysis
|
236
|
-
1. Constraint source (data/method/theory)
|
237
|
-
2. Impact quantification
|
238
|
-
3. Mitigation pathway
|
239
|
-
Example:
|
240
|
-
'Methodology constraint: Single-objective optimization (affects 5% edge cases),
|
241
|
-
mitigated through future multi-task extension'"""
|
242
|
-
|
243
|
-
future_work: List[str]
|
244
|
-
"""Research roadmap items with 3 horizons:
|
245
|
-
1. Immediate extensions (1 year)
|
246
|
-
2. Mid-term directions (2-3 years)
|
247
|
-
3. Long-term vision (5+ years)
|
248
|
-
Example:
|
249
|
-
'Short-term: Adapt framework for vision transformers (ongoing with CVPR submission)'"""
|
250
|
-
|
251
|
-
impact_analysis: List[str]
|
252
|
-
"""Bibliometric impact projections:
|
253
|
-
- Expected citation counts (next 3 years)
|
254
|
-
- Target application domains
|
255
|
-
- Standard adoption potential
|
256
|
-
Example:
|
257
|
-
'Predicted 150+ citations via integration into MMEngine (Alibaba OpenMMLab)'"""
|
91
|
+
"""Technical limitations analysis."""
|
258
92
|
|
259
93
|
bibtex_cite_key: str
|
260
|
-
"""Bibtex
|
94
|
+
"""Bibtex cite key of the original article."""
|
261
95
|
|
262
96
|
def update_cite_key(self, new_cite_key: str) -> Self:
|
263
97
|
"""Update the bibtex_cite_key of the article."""
|
264
98
|
self.bibtex_cite_key = new_cite_key
|
265
99
|
return self
|
266
|
-
|
267
|
-
def _prepare_vectorization_inner(self) -> str:
|
268
|
-
return self.model_dump_json()
|
@@ -16,7 +16,7 @@ from fabricatio.models.extra.article_outline import (
|
|
16
16
|
ArticleOutline,
|
17
17
|
)
|
18
18
|
from fabricatio.models.generic import CensoredAble, Display, PersistentAble, WithRef
|
19
|
-
from fabricatio.
|
19
|
+
from fabricatio.utils import ok
|
20
20
|
|
21
21
|
|
22
22
|
class Paragraph(CensoredAble):
|
@@ -0,0 +1,120 @@
|
|
1
|
+
"""A class representing a problem-solution pair identified during a review process."""
|
2
|
+
|
3
|
+
from typing import List, Literal, Self
|
4
|
+
|
5
|
+
from fabricatio.models.generic import Display, ProposedAble, ProposedUpdateAble, WithBriefing
|
6
|
+
from fabricatio.utils import ask_edit
|
7
|
+
from questionary import Choice, checkbox, text
|
8
|
+
from rich import print as r_print
|
9
|
+
|
10
|
+
|
11
|
+
class Problem(ProposedAble, WithBriefing, Display):
|
12
|
+
"""Represents a problem identified during review."""
|
13
|
+
|
14
|
+
description: str
|
15
|
+
"""Description of the problem, The """
|
16
|
+
|
17
|
+
severity: Literal["low", "medium", "high"]
|
18
|
+
"""Severity level of the problem."""
|
19
|
+
|
20
|
+
category: str
|
21
|
+
"""Category of the problem."""
|
22
|
+
|
23
|
+
location: str
|
24
|
+
"""Location where the problem was identified."""
|
25
|
+
|
26
|
+
recommendation: str
|
27
|
+
"""Recommended solution or action."""
|
28
|
+
|
29
|
+
|
30
|
+
class Solution(ProposedAble, WithBriefing, Display):
|
31
|
+
"""Represents a proposed solution to a problem."""
|
32
|
+
|
33
|
+
operation: str
|
34
|
+
"""Description or identifier of the operation."""
|
35
|
+
|
36
|
+
feasibility: Literal["low", "medium", "high"]
|
37
|
+
"""Feasibility level of the solution."""
|
38
|
+
|
39
|
+
impact: Literal["low", "medium", "high"]
|
40
|
+
"""Impact level of the solution."""
|
41
|
+
|
42
|
+
|
43
|
+
class ProblemSolutions(ProposedUpdateAble):
|
44
|
+
"""Represents a problem-solution pair identified during a review process."""
|
45
|
+
|
46
|
+
problem: Problem
|
47
|
+
"""The problem identified in the review."""
|
48
|
+
solutions: List[Solution]
|
49
|
+
"""A collection of potential solutions."""
|
50
|
+
|
51
|
+
def update_from_inner(self, other: Self) -> Self:
|
52
|
+
"""Update the current instance with another instance's attributes."""
|
53
|
+
self.solutions.clear()
|
54
|
+
self.solutions.extend(other.solutions)
|
55
|
+
return self
|
56
|
+
|
57
|
+
def update_problem(self, problem: Problem) -> Self:
|
58
|
+
"""Update the problem description."""
|
59
|
+
self.problem = problem
|
60
|
+
return self
|
61
|
+
|
62
|
+
def update_solutions(self, solutions: List[Solution]) -> Self:
|
63
|
+
"""Update the list of potential solutions."""
|
64
|
+
self.solutions = solutions
|
65
|
+
return self
|
66
|
+
|
67
|
+
async def edit_problem(self) -> Self:
|
68
|
+
"""Interactively edit the problem description."""
|
69
|
+
self.problem = Problem.model_validate_strings(
|
70
|
+
await text("Please edit the problem below:", default=self.problem.display()).ask_async()
|
71
|
+
)
|
72
|
+
return self
|
73
|
+
|
74
|
+
async def edit_solutions(self) -> Self:
|
75
|
+
"""Interactively edit the list of potential solutions."""
|
76
|
+
r_print(self.problem.display())
|
77
|
+
string_seq = await ask_edit([s.display() for s in self.solutions])
|
78
|
+
self.solutions = [Solution.model_validate_strings(s) for s in string_seq]
|
79
|
+
return self
|
80
|
+
|
81
|
+
|
82
|
+
class Improvement(ProposedAble, Display):
|
83
|
+
"""A class representing an improvement suggestion."""
|
84
|
+
|
85
|
+
problem_solutions: List[ProblemSolutions]
|
86
|
+
"""Collection of problems identified during review along with their potential solutions."""
|
87
|
+
|
88
|
+
async def supervisor_check(self, check_solutions: bool = True) -> Self:
|
89
|
+
"""Perform an interactive review session to filter problems and solutions.
|
90
|
+
|
91
|
+
Presents an interactive prompt allowing a supervisor to select which
|
92
|
+
problems (and optionally solutions) should be retained in the final review.
|
93
|
+
|
94
|
+
Args:
|
95
|
+
check_solutions (bool, optional): When True, also prompts for filtering
|
96
|
+
individual solutions for each retained problem. Defaults to False.
|
97
|
+
|
98
|
+
Returns:
|
99
|
+
Self: The current instance with filtered problems and solutions.
|
100
|
+
"""
|
101
|
+
# Choose the problems to retain
|
102
|
+
chosen_ones: List[ProblemSolutions] = await checkbox(
|
103
|
+
"Please choose the problems you want to retain.(Default: retain all)",
|
104
|
+
choices=[Choice(p.problem.name, p, checked=True) for p in self.problem_solutions],
|
105
|
+
).ask_async()
|
106
|
+
self.problem_solutions = [await p.edit_problem() for p in chosen_ones]
|
107
|
+
if not check_solutions:
|
108
|
+
return self
|
109
|
+
|
110
|
+
# Choose the solutions to retain
|
111
|
+
for to_exam in self.problem_solutions:
|
112
|
+
to_exam.update_solutions(
|
113
|
+
await checkbox(
|
114
|
+
f"Please choose the solutions you want to retain.(Default: retain all)\n\t`{to_exam.problem}`",
|
115
|
+
choices=[Choice(s.name, s, checked=True) for s in to_exam.solutions],
|
116
|
+
).ask_async()
|
117
|
+
)
|
118
|
+
await to_exam.edit_solutions()
|
119
|
+
|
120
|
+
return self
|
@@ -0,0 +1,23 @@
|
|
1
|
+
"""A module containing classes related to rule sets and rules."""
|
2
|
+
|
3
|
+
from typing import List
|
4
|
+
|
5
|
+
from fabricatio.models.generic import Described, Display, PersistentAble, ProposedAble, WithBriefing
|
6
|
+
|
7
|
+
|
8
|
+
class Rule(WithBriefing,ProposedAble,Display):
|
9
|
+
"""Represents a rule or guideline for a specific topic."""
|
10
|
+
|
11
|
+
violation_examples: List[str]
|
12
|
+
"""Examples of violations of the rule."""
|
13
|
+
compliance_examples: List[str]
|
14
|
+
"""Examples of how to comply with the rule."""
|
15
|
+
|
16
|
+
|
17
|
+
class RuleSet(ProposedAble, Display, PersistentAble, Described):
|
18
|
+
"""Represents a collection of rules and guidelines for a particular topic."""
|
19
|
+
|
20
|
+
title: str
|
21
|
+
"""The title of the rule set."""
|
22
|
+
rules: List[Rule]
|
23
|
+
"""The rules and guidelines contained in the rule set."""
|
fabricatio/models/generic.py
CHANGED
@@ -6,13 +6,15 @@ from pathlib import Path
|
|
6
6
|
from typing import Any, Callable, Dict, Iterable, List, Optional, Self, Union, final, overload
|
7
7
|
|
8
8
|
import orjson
|
9
|
+
import rtoml
|
9
10
|
from fabricatio._rust import blake3_hash
|
10
11
|
from fabricatio._rust_instances import TEMPLATE_MANAGER
|
11
12
|
from fabricatio.config import configs
|
12
13
|
from fabricatio.fs.readers import MAGIKA, safe_text_read
|
13
14
|
from fabricatio.journal import logger
|
14
|
-
from fabricatio.models.utils import ok
|
15
15
|
from fabricatio.parser import JsonCapture
|
16
|
+
from fabricatio.utils import ok
|
17
|
+
from litellm.utils import token_counter
|
16
18
|
from pydantic import (
|
17
19
|
BaseModel,
|
18
20
|
ConfigDict,
|
@@ -63,7 +65,7 @@ class Named(Base):
|
|
63
65
|
class Described(Base):
|
64
66
|
"""Class that includes a description attribute."""
|
65
67
|
|
66
|
-
description: str = Field(
|
68
|
+
description: str = Field(frozen=True)
|
67
69
|
"""The description of the object."""
|
68
70
|
|
69
71
|
|
@@ -98,14 +100,28 @@ class WithRef[T](Base):
|
|
98
100
|
self._reference, f"`{self.__class__.__name__}`' s `_reference` field is None. Have you called `update_ref`?"
|
99
101
|
)
|
100
102
|
|
101
|
-
|
103
|
+
@overload
|
104
|
+
def update_ref[S: WithRef](self: S, reference: T) -> S: ...
|
105
|
+
|
106
|
+
@overload
|
107
|
+
def update_ref[S: WithRef](self: S, reference: "WithRef[T]") -> S: ...
|
108
|
+
|
109
|
+
@overload
|
110
|
+
def update_ref[S: WithRef](self: S, reference: None = None) -> S: ...
|
111
|
+
def update_ref[S: WithRef](self: S, reference: Union[T, "WithRef[T]", None] = None) -> S: # noqa: PYI019
|
102
112
|
"""Update the reference of the object."""
|
103
113
|
if isinstance(reference, self.__class__):
|
104
114
|
self._reference = reference.referenced
|
105
115
|
else:
|
106
|
-
self._reference = reference
|
116
|
+
self._reference = reference # pyright: ignore [reportAttributeAccessIssue]
|
107
117
|
return self
|
108
118
|
|
119
|
+
def derive[S: WithRef](self: S, reference: Any) -> S: # noqa: PYI019
|
120
|
+
"""Derive a new object from the current object."""
|
121
|
+
new = self.model_copy()
|
122
|
+
new._reference = reference
|
123
|
+
return new
|
124
|
+
|
109
125
|
|
110
126
|
class PersistentAble(Base):
|
111
127
|
"""Class that provides a method to persist the object."""
|
@@ -120,10 +136,10 @@ class PersistentAble(Base):
|
|
120
136
|
Self: The current instance of the object.
|
121
137
|
"""
|
122
138
|
p = Path(path)
|
123
|
-
out = self.
|
139
|
+
out = rtoml.dumps(self.model_dump())
|
124
140
|
|
125
141
|
# Generate a timestamp in the format YYYYMMDD_HHMMSS
|
126
|
-
timestamp = datetime.now().strftime("%Y%m%
|
142
|
+
timestamp = datetime.now().strftime("%Y%m%d")
|
127
143
|
|
128
144
|
# Generate the hash
|
129
145
|
file_hash = blake3_hash(out.encode())[:6]
|
@@ -150,7 +166,7 @@ class PersistentAble(Base):
|
|
150
166
|
Returns:
|
151
167
|
Self: The current instance of the object.
|
152
168
|
"""
|
153
|
-
return cls.
|
169
|
+
return cls.model_validate(rtoml.load(path))
|
154
170
|
|
155
171
|
|
156
172
|
class ModelHash(Base):
|
@@ -220,27 +236,6 @@ class WithBriefing(Named, Described):
|
|
220
236
|
"""
|
221
237
|
return f"{self.name}: {self.description}" if self.description else self.name
|
222
238
|
|
223
|
-
def _prepend_inner(self, input_text: str) -> str:
|
224
|
-
return f"# your personal briefing: \n{self.briefing}\n{input_text}"
|
225
|
-
|
226
|
-
def prepend_sys_msg[D: (Dict[str, Any], str)](self, system_msg_like: D = "") -> Dict[str, Any]:
|
227
|
-
"""Prepend the system message with the briefing.
|
228
|
-
|
229
|
-
Args:
|
230
|
-
system_msg_like (str | dict): The system message or a dictionary containing the system message.
|
231
|
-
|
232
|
-
Returns:
|
233
|
-
dict: The system message with the briefing prepended.
|
234
|
-
"""
|
235
|
-
match system_msg_like:
|
236
|
-
case dict(d):
|
237
|
-
d["system_message"] = self._prepend_inner(d.get("system_message", ""))
|
238
|
-
return d
|
239
|
-
case str(s):
|
240
|
-
return {"system_message": self._prepend_inner(s)}
|
241
|
-
case _:
|
242
|
-
raise TypeError(f"{system_msg_like} is not a dict or str")
|
243
|
-
|
244
239
|
|
245
240
|
class UnsortGenerate(GenerateJsonSchema):
|
246
241
|
"""Class that provides a reverse JSON schema of the model."""
|
@@ -441,13 +436,13 @@ class WithDependency(Base):
|
|
441
436
|
)
|
442
437
|
|
443
438
|
|
444
|
-
class
|
439
|
+
class Vectorizable(Base):
|
445
440
|
"""Class that prepares the vectorization of the model."""
|
446
441
|
|
447
|
-
@abstractmethod
|
448
442
|
def _prepare_vectorization_inner(self) -> str:
|
449
|
-
|
443
|
+
return rtoml.dumps(self.model_dump())
|
450
444
|
|
445
|
+
@final
|
451
446
|
def prepare_vectorization(self, max_length: Optional[int] = None) -> str:
|
452
447
|
"""Prepare the vectorization of the model.
|
453
448
|
|
@@ -456,8 +451,8 @@ class PrepareVectorization(Base):
|
|
456
451
|
"""
|
457
452
|
max_length = max_length or configs.embedding.max_sequence_length
|
458
453
|
chunk = self._prepare_vectorization_inner()
|
459
|
-
if max_length and
|
460
|
-
logger.error(err := f"Chunk exceeds maximum sequence length {max_length}
|
454
|
+
if max_length and (length := token_counter(text=chunk)) > max_length:
|
455
|
+
logger.error(err := f"Chunk exceeds maximum sequence length {max_length}, got {length},see {chunk}")
|
461
456
|
raise ValueError(err)
|
462
457
|
|
463
458
|
return chunk
|
fabricatio/models/role.py
CHANGED
@@ -8,11 +8,12 @@ from fabricatio.core import env
|
|
8
8
|
from fabricatio.journal import logger
|
9
9
|
from fabricatio.models.action import WorkFlow
|
10
10
|
from fabricatio.models.events import Event
|
11
|
+
from fabricatio.models.generic import WithBriefing
|
11
12
|
from fabricatio.models.tool import ToolBox
|
12
13
|
from pydantic import Field
|
13
14
|
|
14
15
|
|
15
|
-
class Role(ProposeTask, HandleTask, Correct):
|
16
|
+
class Role(WithBriefing, ProposeTask, HandleTask, Correct):
|
16
17
|
"""Class that represents a role with a registry of events and workflows.
|
17
18
|
|
18
19
|
A Role serves as a container for workflows, managing their registration to events
|
@@ -22,6 +23,8 @@ class Role(ProposeTask, HandleTask, Correct):
|
|
22
23
|
registry: Mapping of events to workflows that handle them
|
23
24
|
toolboxes: Set of toolboxes available to this role and its workflows
|
24
25
|
"""
|
26
|
+
description:str =""
|
27
|
+
"""A brief description of the role's responsibilities and capabilities."""
|
25
28
|
|
26
29
|
registry: dict[Event | str, WorkFlow] = Field(default_factory=dict)
|
27
30
|
"""The registry of events and workflows."""
|
fabricatio/models/usages.py
CHANGED
@@ -14,8 +14,9 @@ from fabricatio.models.generic import ScopedConfig, WithBriefing
|
|
14
14
|
from fabricatio.models.kwargs_types import ChooseKwargs, EmbeddingKwargs, GenerateKwargs, LLMKwargs, ValidateKwargs
|
15
15
|
from fabricatio.models.task import Task
|
16
16
|
from fabricatio.models.tool import Tool, ToolBox
|
17
|
-
from fabricatio.models.utils import Messages
|
17
|
+
from fabricatio.models.utils import Messages
|
18
18
|
from fabricatio.parser import GenericCapture, JsonCapture
|
19
|
+
from fabricatio.utils import ok
|
19
20
|
from litellm import RateLimitError, Router, stream_chunk_builder # pyright: ignore [reportPrivateImportUsage]
|
20
21
|
from litellm.types.router import Deployment, LiteLLM_Params, ModelInfo
|
21
22
|
from litellm.types.utils import (
|
@@ -280,7 +281,7 @@ class LLMUsage(ScopedConfig):
|
|
280
281
|
question: str | List[str],
|
281
282
|
validator: Callable[[str], T | None],
|
282
283
|
default: Optional[T] = None,
|
283
|
-
max_validations: PositiveInt =
|
284
|
+
max_validations: PositiveInt = 3,
|
284
285
|
co_extractor: Optional[GenerateKwargs] = None,
|
285
286
|
**kwargs: Unpack[GenerateKwargs],
|
286
287
|
) -> Optional[T] | List[Optional[T]] | List[T] | T:
|
@@ -338,7 +339,7 @@ class LLMUsage(ScopedConfig):
|
|
338
339
|
|
339
340
|
return await (gather(*[_inner(q) for q in question]) if isinstance(question, list) else _inner(question))
|
340
341
|
|
341
|
-
async def
|
342
|
+
async def alist_str(
|
342
343
|
self, requirement: str, k: NonNegativeInt = 0, **kwargs: Unpack[ValidateKwargs[List[str]]]
|
343
344
|
) -> Optional[List[str]]:
|
344
345
|
"""Asynchronously generates a list of strings based on a given requirement.
|
@@ -360,6 +361,7 @@ class LLMUsage(ScopedConfig):
|
|
360
361
|
**kwargs,
|
361
362
|
)
|
362
363
|
|
364
|
+
|
363
365
|
async def apathstr(self, requirement: str, **kwargs: Unpack[ChooseKwargs[List[str]]]) -> Optional[List[str]]:
|
364
366
|
"""Asynchronously generates a list of strings based on a given requirement.
|
365
367
|
|
@@ -370,7 +372,7 @@ class LLMUsage(ScopedConfig):
|
|
370
372
|
Returns:
|
371
373
|
List[str]: The validated response as a list of strings.
|
372
374
|
"""
|
373
|
-
return await self.
|
375
|
+
return await self.alist_str(
|
374
376
|
TEMPLATE_MANAGER.render_template(
|
375
377
|
configs.templates.pathstr_template,
|
376
378
|
{"requirement": requirement},
|
@@ -550,8 +552,8 @@ class EmbeddingUsage(LLMUsage):
|
|
550
552
|
"""
|
551
553
|
# check seq length
|
552
554
|
max_len = self.embedding_max_sequence_length or configs.embedding.max_sequence_length
|
553
|
-
if max_len and any(
|
554
|
-
logger.error(err := f"Input text exceeds maximum sequence length {max_len}.")
|
555
|
+
if max_len and any(length:=(token_counter(text=t)) > max_len for t in input_text):
|
556
|
+
logger.error(err := f"Input text exceeds maximum sequence length {max_len}, got {length}.")
|
555
557
|
raise ValueError(err)
|
556
558
|
|
557
559
|
return await litellm.aembedding(
|