fabricatio 0.2.8.dev2__cp312-cp312-win_amd64.whl → 0.2.8.dev4__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 +112 -121
- fabricatio/actions/article_rag.py +55 -45
- fabricatio/actions/output.py +4 -3
- fabricatio/actions/rag.py +3 -3
- fabricatio/capabilities/censor.py +87 -0
- fabricatio/capabilities/check.py +194 -0
- fabricatio/capabilities/correct.py +142 -98
- fabricatio/capabilities/propose.py +20 -4
- fabricatio/capabilities/rag.py +3 -2
- fabricatio/capabilities/rating.py +67 -22
- fabricatio/capabilities/review.py +18 -187
- fabricatio/capabilities/task.py +8 -9
- fabricatio/config.py +11 -3
- fabricatio/models/action.py +8 -5
- fabricatio/models/adv_kwargs_types.py +25 -0
- fabricatio/models/extra/advanced_judge.py +10 -7
- fabricatio/models/extra/article_base.py +47 -27
- fabricatio/models/extra/article_essence.py +40 -209
- fabricatio/models/extra/article_main.py +3 -4
- fabricatio/models/extra/patches.py +7 -0
- fabricatio/models/extra/problem.py +153 -0
- fabricatio/models/extra/rule.py +21 -0
- fabricatio/models/generic.py +71 -37
- fabricatio/models/kwargs_types.py +23 -17
- fabricatio/models/role.py +4 -1
- fabricatio/models/usages.py +17 -20
- fabricatio/models/utils.py +0 -46
- fabricatio/parser.py +7 -8
- fabricatio/utils.py +54 -0
- {fabricatio-0.2.8.dev2.data → fabricatio-0.2.8.dev4.data}/scripts/tdown.exe +0 -0
- {fabricatio-0.2.8.dev2.dist-info → fabricatio-0.2.8.dev4.dist-info}/METADATA +2 -1
- fabricatio-0.2.8.dev4.dist-info/RECORD +56 -0
- fabricatio-0.2.8.dev2.dist-info/RECORD +0 -49
- {fabricatio-0.2.8.dev2.dist-info → fabricatio-0.2.8.dev4.dist-info}/WHEEL +0 -0
- {fabricatio-0.2.8.dev2.dist-info → fabricatio-0.2.8.dev4.dist-info}/licenses/LICENSE +0 -0
@@ -2,9 +2,8 @@
|
|
2
2
|
|
3
3
|
from abc import ABC, abstractmethod
|
4
4
|
from enum import StrEnum
|
5
|
-
from functools import cache
|
6
5
|
from itertools import chain
|
7
|
-
from typing import Generator, List, Optional, Self, Tuple
|
6
|
+
from typing import Generator, List, Optional, Self, Tuple, overload
|
8
7
|
|
9
8
|
from fabricatio.models.generic import (
|
10
9
|
AsPrompt,
|
@@ -16,6 +15,7 @@ from fabricatio.models.generic import (
|
|
16
15
|
PersistentAble,
|
17
16
|
ProposedUpdateAble,
|
18
17
|
ResolveUpdateConflict,
|
18
|
+
SequencePatch,
|
19
19
|
)
|
20
20
|
|
21
21
|
|
@@ -30,8 +30,7 @@ class ReferringType(StrEnum):
|
|
30
30
|
type RefKey = Tuple[str, Optional[str], Optional[str]]
|
31
31
|
|
32
32
|
|
33
|
-
|
34
|
-
class ArticleRef(CensoredAble, Display, ProposedUpdateAble):
|
33
|
+
class ArticleRef(CensoredAble, ProposedUpdateAble):
|
35
34
|
"""Reference to a specific chapter, section or subsection within the article. You SHALL not refer to an article component that is external and not present within our own article.
|
36
35
|
|
37
36
|
Examples:
|
@@ -122,30 +121,10 @@ class ArticleMetaData(CensoredAble, Display):
|
|
122
121
|
"""Do not add any prefix or suffix to the title. should not contain special characters."""
|
123
122
|
|
124
123
|
|
125
|
-
class
|
126
|
-
"""Base class for patches."""
|
127
|
-
|
128
|
-
tweaked: List[T]
|
129
|
-
"""Tweaked content list"""
|
130
|
-
def update_from_inner(self, other: Self) -> Self:
|
131
|
-
"""Updates the current instance with the attributes of another instance."""
|
132
|
-
self.tweaked.clear()
|
133
|
-
self.tweaked.extend(other.tweaked)
|
134
|
-
return self
|
135
|
-
|
136
|
-
|
137
|
-
@classmethod
|
138
|
-
def default(cls) -> Self:
|
139
|
-
"""Defaults to empty list."""
|
140
|
-
return cls(tweaked=[])
|
141
|
-
|
142
|
-
|
143
|
-
class ArticleRefPatch(Patch[ArticleRef]):
|
124
|
+
class ArticleRefSequencePatch(SequencePatch[ArticleRef]):
|
144
125
|
"""Patch for article refs."""
|
145
126
|
|
146
127
|
|
147
|
-
|
148
|
-
|
149
128
|
class ArticleOutlineBase(
|
150
129
|
ArticleMetaData,
|
151
130
|
ResolveUpdateConflict,
|
@@ -340,6 +319,34 @@ class ArticleBase[T: ChapterBase](FinalizedDumpAble, AsPrompt, ABC):
|
|
340
319
|
yield sec
|
341
320
|
yield from sec.subsections
|
342
321
|
|
322
|
+
def iter_support_on(self, rev: bool = False) -> Generator[ArticleRef, None, None]:
|
323
|
+
"""Iterates over all references that the article components support.
|
324
|
+
|
325
|
+
Args:
|
326
|
+
rev (bool): If True, iterate in reverse order.
|
327
|
+
|
328
|
+
Yields:
|
329
|
+
ArticleRef: Each reference that the article components support.
|
330
|
+
"""
|
331
|
+
if rev:
|
332
|
+
yield from chain(*[a.support_to for a in self.iter_dfs_rev()])
|
333
|
+
return
|
334
|
+
yield from chain(*[a.support_to for a in self.iter_dfs()])
|
335
|
+
|
336
|
+
def iter_depend_on(self, rev: bool = False) -> Generator[ArticleRef, None, None]:
|
337
|
+
"""Iterates over all references that the article components depend on.
|
338
|
+
|
339
|
+
Args:
|
340
|
+
rev (bool): If True, iterate in reverse order.
|
341
|
+
|
342
|
+
Yields:
|
343
|
+
ArticleRef: Each reference that the article components depend on.
|
344
|
+
"""
|
345
|
+
if rev:
|
346
|
+
yield from chain(*[a.depend_on for a in self.iter_dfs_rev()])
|
347
|
+
return
|
348
|
+
yield from chain(*[a.depend_on for a in self.iter_dfs()])
|
349
|
+
|
343
350
|
def iter_sections(self) -> Generator[Tuple[ChapterBase, SectionBase], None, None]:
|
344
351
|
"""Iterates through all sections in the article.
|
345
352
|
|
@@ -369,7 +376,13 @@ class ArticleBase[T: ChapterBase](FinalizedDumpAble, AsPrompt, ABC):
|
|
369
376
|
return component, summary
|
370
377
|
return None
|
371
378
|
|
372
|
-
|
379
|
+
@overload
|
380
|
+
def find_illegal_ref(self, gather_identical: bool) -> Optional[Tuple[ArticleRef | List[ArticleRef], str]]: ...
|
381
|
+
|
382
|
+
@overload
|
383
|
+
def find_illegal_ref(self) -> Optional[Tuple[ArticleRef, str]]: ...
|
384
|
+
|
385
|
+
def find_illegal_ref(self, gather_identical: bool = False) -> Optional[Tuple[ArticleRef | List[ArticleRef], str]]:
|
373
386
|
"""Finds the first illegal component in the outline.
|
374
387
|
|
375
388
|
Returns:
|
@@ -380,8 +393,15 @@ class ArticleBase[T: ChapterBase](FinalizedDumpAble, AsPrompt, ABC):
|
|
380
393
|
for ref in chain(component.depend_on, component.support_to):
|
381
394
|
if not ref.deref(self):
|
382
395
|
summary += f"Invalid internal reference in `{component.__class__.__name__}` titled `{component.title}`, because the referred {ref.referring_type} is not exists within the article, see the original obj dump: {ref.model_dump()}\n"
|
383
|
-
if summary:
|
396
|
+
if summary and not gather_identical:
|
384
397
|
return ref, summary
|
398
|
+
if summary and gather_identical:
|
399
|
+
return [
|
400
|
+
identical_ref
|
401
|
+
for identical_ref in chain(self.iter_depend_on(), self.iter_support_on())
|
402
|
+
if identical_ref == ref
|
403
|
+
], summary
|
404
|
+
|
385
405
|
return None
|
386
406
|
|
387
407
|
def finalized_dump(self) -> str:
|
@@ -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()
|
@@ -8,15 +8,14 @@ from fabricatio.models.extra.article_base import (
|
|
8
8
|
ArticleBase,
|
9
9
|
ArticleOutlineBase,
|
10
10
|
ChapterBase,
|
11
|
-
Patch,
|
12
11
|
SectionBase,
|
13
12
|
SubSectionBase,
|
14
13
|
)
|
15
14
|
from fabricatio.models.extra.article_outline import (
|
16
15
|
ArticleOutline,
|
17
16
|
)
|
18
|
-
from fabricatio.models.generic import CensoredAble, Display, PersistentAble, WithRef
|
19
|
-
from fabricatio.
|
17
|
+
from fabricatio.models.generic import CensoredAble, Display, PersistentAble, SequencePatch, WithRef
|
18
|
+
from fabricatio.utils import ok
|
20
19
|
|
21
20
|
|
22
21
|
class Paragraph(CensoredAble):
|
@@ -32,7 +31,7 @@ class Paragraph(CensoredAble):
|
|
32
31
|
"""The actual content of the paragraph, represented as a string."""
|
33
32
|
|
34
33
|
|
35
|
-
class
|
34
|
+
class ArticleParagraphSequencePatch(SequencePatch[Paragraph]):
|
36
35
|
"""Patch for `Paragraph` list of `ArticleSubsection`."""
|
37
36
|
|
38
37
|
|
@@ -0,0 +1,7 @@
|
|
1
|
+
"""A patch class for updating the description and name of a `WithBriefing` object."""
|
2
|
+
|
3
|
+
from fabricatio.models.generic import Patch, WithBriefing
|
4
|
+
|
5
|
+
|
6
|
+
class BriefingPatch[T:WithBriefing](Patch[T], WithBriefing):
|
7
|
+
"""Patch class for updating the description and name of a `WithBriefing` object."""
|
@@ -0,0 +1,153 @@
|
|
1
|
+
"""A class representing a problem-solution pair identified during a review process."""
|
2
|
+
|
3
|
+
from itertools import chain
|
4
|
+
from typing import List, Literal, Optional, Self
|
5
|
+
|
6
|
+
from fabricatio.journal import logger
|
7
|
+
from fabricatio.models.generic import SketchedAble, WithBriefing
|
8
|
+
from fabricatio.utils import ask_edit
|
9
|
+
from questionary import Choice, checkbox, text
|
10
|
+
from rich import print as r_print
|
11
|
+
|
12
|
+
|
13
|
+
class Problem(SketchedAble, WithBriefing):
|
14
|
+
"""Represents a problem identified during review."""
|
15
|
+
|
16
|
+
description: str
|
17
|
+
"""Description of the problem, The """
|
18
|
+
|
19
|
+
severity: Literal["low", "medium", "high"]
|
20
|
+
"""Severity level of the problem."""
|
21
|
+
|
22
|
+
category: str
|
23
|
+
"""Category of the problem."""
|
24
|
+
|
25
|
+
location: str
|
26
|
+
"""Location where the problem was identified."""
|
27
|
+
|
28
|
+
recommendation: str
|
29
|
+
"""Recommended solution or action."""
|
30
|
+
|
31
|
+
|
32
|
+
class Solution(SketchedAble, WithBriefing):
|
33
|
+
"""Represents a proposed solution to a problem."""
|
34
|
+
|
35
|
+
description: str
|
36
|
+
"""Description of the solution, including a detailed description of the execution steps, and the mechanics, principle or fact."""
|
37
|
+
|
38
|
+
execute_steps: List[str]
|
39
|
+
"""A list of steps to execute to implement the solution, which is expected to be able to finally solve the corresponding problem."""
|
40
|
+
|
41
|
+
feasibility: Literal["low", "medium", "high"]
|
42
|
+
"""Feasibility level of the solution."""
|
43
|
+
|
44
|
+
impact: Literal["low", "medium", "high"]
|
45
|
+
"""Impact level of the solution."""
|
46
|
+
|
47
|
+
|
48
|
+
class ProblemSolutions(SketchedAble):
|
49
|
+
"""Represents a problem-solution pair identified during a review process."""
|
50
|
+
|
51
|
+
problem: Problem
|
52
|
+
"""The problem identified in the review."""
|
53
|
+
solutions: List[Solution]
|
54
|
+
"""A collection of potential solutions."""
|
55
|
+
|
56
|
+
def update_from_inner(self, other: Self) -> Self:
|
57
|
+
"""Update the current instance with another instance's attributes."""
|
58
|
+
self.solutions.clear()
|
59
|
+
self.solutions.extend(other.solutions)
|
60
|
+
return self
|
61
|
+
|
62
|
+
def update_problem(self, problem: Problem) -> Self:
|
63
|
+
"""Update the problem description."""
|
64
|
+
self.problem = problem
|
65
|
+
return self
|
66
|
+
|
67
|
+
def update_solutions(self, solutions: List[Solution]) -> Self:
|
68
|
+
"""Update the list of potential solutions."""
|
69
|
+
self.solutions = solutions
|
70
|
+
return self
|
71
|
+
|
72
|
+
async def edit_problem(self) -> Self:
|
73
|
+
"""Interactively edit the problem description."""
|
74
|
+
self.problem = Problem.model_validate_strings(
|
75
|
+
await text("Please edit the problem below:", default=self.problem.display()).ask_async()
|
76
|
+
)
|
77
|
+
return self
|
78
|
+
|
79
|
+
async def edit_solutions(self) -> Self:
|
80
|
+
"""Interactively edit the list of potential solutions."""
|
81
|
+
r_print(self.problem.display())
|
82
|
+
string_seq = await ask_edit([s.display() for s in self.solutions])
|
83
|
+
self.solutions = [Solution.model_validate_strings(s) for s in string_seq]
|
84
|
+
return self
|
85
|
+
|
86
|
+
def decided(self) -> bool:
|
87
|
+
"""Check if the improvement is decided."""
|
88
|
+
return len(self.solutions) == 1
|
89
|
+
|
90
|
+
def final_solution(self) -> Optional[Solution]:
|
91
|
+
"""Get the final solution."""
|
92
|
+
if not self.decided():
|
93
|
+
logger.error(
|
94
|
+
f"There is more than one solution for problem {self.problem.name}, please decide which solution is eventually adopted."
|
95
|
+
)
|
96
|
+
return None
|
97
|
+
return self.solutions[0]
|
98
|
+
|
99
|
+
|
100
|
+
class Improvement(SketchedAble):
|
101
|
+
"""A class representing an improvement suggestion."""
|
102
|
+
|
103
|
+
focused_on: str
|
104
|
+
"""The focused on topic of the improvement"""
|
105
|
+
|
106
|
+
problem_solutions: List[ProblemSolutions]
|
107
|
+
"""Collection of problems identified during review along with their potential solutions."""
|
108
|
+
|
109
|
+
async def supervisor_check(self, check_solutions: bool = True) -> Self:
|
110
|
+
"""Perform an interactive review session to filter problems and solutions.
|
111
|
+
|
112
|
+
Presents an interactive prompt allowing a supervisor to select which
|
113
|
+
problems (and optionally solutions) should be retained in the final review.
|
114
|
+
|
115
|
+
Args:
|
116
|
+
check_solutions (bool, optional): When True, also prompts for filtering
|
117
|
+
individual solutions for each retained problem. Defaults to False.
|
118
|
+
|
119
|
+
Returns:
|
120
|
+
Self: The current instance with filtered problems and solutions.
|
121
|
+
"""
|
122
|
+
# Choose the problems to retain
|
123
|
+
chosen_ones: List[ProblemSolutions] = await checkbox(
|
124
|
+
"Please choose the problems you want to retain.(Default: retain all)",
|
125
|
+
choices=[Choice(p.problem.name, p, checked=True) for p in self.problem_solutions],
|
126
|
+
).ask_async()
|
127
|
+
self.problem_solutions = [await p.edit_problem() for p in chosen_ones]
|
128
|
+
if not check_solutions:
|
129
|
+
return self
|
130
|
+
|
131
|
+
# Choose the solutions to retain
|
132
|
+
for to_exam in self.problem_solutions:
|
133
|
+
to_exam.update_solutions(
|
134
|
+
await checkbox(
|
135
|
+
f"Please choose the solutions you want to retain.(Default: retain all)\n\t`{to_exam.problem}`",
|
136
|
+
choices=[Choice(s.name, s, checked=True) for s in to_exam.solutions],
|
137
|
+
).ask_async()
|
138
|
+
)
|
139
|
+
await to_exam.edit_solutions()
|
140
|
+
|
141
|
+
return self
|
142
|
+
|
143
|
+
def decided(self) -> bool:
|
144
|
+
"""Check if the improvement is decided."""
|
145
|
+
return all(ps.decided() for ps in self.problem_solutions)
|
146
|
+
|
147
|
+
@classmethod
|
148
|
+
def gather(cls, *improvements: Self) -> Self:
|
149
|
+
"""Gather multiple improvements into a single instance."""
|
150
|
+
return cls(
|
151
|
+
focused_on="\n".join(imp.focused_on for imp in improvements),
|
152
|
+
problem_solutions=list(chain(*(imp.problem_solutions for imp in improvements))),
|
153
|
+
)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
"""A module containing classes related to rule sets and rules."""
|
2
|
+
|
3
|
+
from typing import List
|
4
|
+
|
5
|
+
from fabricatio.models.generic import 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, WithBriefing):
|
18
|
+
"""Represents a collection of rules and guidelines for a particular topic."""
|
19
|
+
|
20
|
+
rules: List[Rule]
|
21
|
+
"""The rules and guidelines contained in the rule set."""
|