fabricatio 0.2.8.dev1__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.
Files changed (35) hide show
  1. fabricatio/_rust.cp312-win_amd64.pyd +0 -0
  2. fabricatio/_rust.pyi +50 -0
  3. fabricatio/actions/article.py +103 -65
  4. fabricatio/actions/article_rag.py +73 -19
  5. fabricatio/actions/output.py +39 -6
  6. fabricatio/actions/rag.py +3 -3
  7. fabricatio/capabilities/check.py +97 -0
  8. fabricatio/capabilities/correct.py +7 -6
  9. fabricatio/capabilities/propose.py +20 -4
  10. fabricatio/capabilities/rag.py +3 -2
  11. fabricatio/capabilities/rating.py +7 -10
  12. fabricatio/capabilities/review.py +18 -187
  13. fabricatio/capabilities/task.py +8 -9
  14. fabricatio/config.py +2 -0
  15. fabricatio/fs/curd.py +4 -0
  16. fabricatio/models/action.py +10 -5
  17. fabricatio/models/extra/advanced_judge.py +16 -9
  18. fabricatio/models/extra/article_base.py +53 -10
  19. fabricatio/models/extra/article_essence.py +47 -171
  20. fabricatio/models/extra/article_main.py +6 -1
  21. fabricatio/models/extra/article_proposal.py +19 -1
  22. fabricatio/models/extra/problem.py +120 -0
  23. fabricatio/models/extra/rule.py +23 -0
  24. fabricatio/models/generic.py +50 -42
  25. fabricatio/models/role.py +4 -1
  26. fabricatio/models/usages.py +8 -6
  27. fabricatio/models/utils.py +0 -46
  28. fabricatio/utils.py +54 -0
  29. fabricatio-0.2.8.dev3.data/scripts/tdown.exe +0 -0
  30. {fabricatio-0.2.8.dev1.dist-info → fabricatio-0.2.8.dev3.dist-info}/METADATA +2 -1
  31. fabricatio-0.2.8.dev3.dist-info/RECORD +53 -0
  32. fabricatio-0.2.8.dev1.data/scripts/tdown.exe +0 -0
  33. fabricatio-0.2.8.dev1.dist-info/RECORD +0 -49
  34. {fabricatio-0.2.8.dev1.dist-info → fabricatio-0.2.8.dev3.dist-info}/WHEEL +0 -0
  35. {fabricatio-0.2.8.dev1.dist-info → fabricatio-0.2.8.dev3.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,
@@ -30,7 +29,6 @@ class ReferringType(StrEnum):
30
29
  type RefKey = Tuple[str, Optional[str], Optional[str]]
31
30
 
32
31
 
33
- @cache
34
32
  class ArticleRef(CensoredAble, Display, ProposedUpdateAble):
35
33
  """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
34
 
@@ -122,11 +120,11 @@ class ArticleMetaData(CensoredAble, Display):
122
120
  """Do not add any prefix or suffix to the title. should not contain special characters."""
123
121
 
124
122
 
125
- class ArticleRefPatch(ProposedUpdateAble, Display):
126
- """Patch for article refs."""
123
+ class Patch[T](ProposedUpdateAble, Display):
124
+ """Base class for patches."""
127
125
 
128
- tweaked: List[ArticleRef]
129
- """Tweaked refs"""
126
+ tweaked: List[T]
127
+ """Tweaked content list"""
130
128
 
131
129
  def update_from_inner(self, other: Self) -> Self:
132
130
  """Updates the current instance with the attributes of another instance."""
@@ -135,11 +133,15 @@ class ArticleRefPatch(ProposedUpdateAble, Display):
135
133
  return self
136
134
 
137
135
  @classmethod
138
- def default(cls) -> "ArticleRefPatch":
136
+ def default(cls) -> Self:
139
137
  """Defaults to empty list."""
140
138
  return cls(tweaked=[])
141
139
 
142
140
 
141
+ class ArticleRefPatch(Patch[ArticleRef]):
142
+ """Patch for article refs."""
143
+
144
+
143
145
  class ArticleOutlineBase(
144
146
  ArticleMetaData,
145
147
  ResolveUpdateConflict,
@@ -334,6 +336,34 @@ class ArticleBase[T: ChapterBase](FinalizedDumpAble, AsPrompt, ABC):
334
336
  yield sec
335
337
  yield from sec.subsections
336
338
 
339
+ def iter_support_on(self, rev: bool = False) -> Generator[ArticleRef, None, None]:
340
+ """Iterates over all references that the article components support.
341
+
342
+ Args:
343
+ rev (bool): If True, iterate in reverse order.
344
+
345
+ Yields:
346
+ ArticleRef: Each reference that the article components support.
347
+ """
348
+ if rev:
349
+ yield from chain(*[a.support_to for a in self.iter_dfs_rev()])
350
+ return
351
+ yield from chain(*[a.support_to for a in self.iter_dfs()])
352
+
353
+ def iter_depend_on(self, rev: bool = False) -> Generator[ArticleRef, None, None]:
354
+ """Iterates over all references that the article components depend on.
355
+
356
+ Args:
357
+ rev (bool): If True, iterate in reverse order.
358
+
359
+ Yields:
360
+ ArticleRef: Each reference that the article components depend on.
361
+ """
362
+ if rev:
363
+ yield from chain(*[a.depend_on for a in self.iter_dfs_rev()])
364
+ return
365
+ yield from chain(*[a.depend_on for a in self.iter_dfs()])
366
+
337
367
  def iter_sections(self) -> Generator[Tuple[ChapterBase, SectionBase], None, None]:
338
368
  """Iterates through all sections in the article.
339
369
 
@@ -363,7 +393,13 @@ class ArticleBase[T: ChapterBase](FinalizedDumpAble, AsPrompt, ABC):
363
393
  return component, summary
364
394
  return None
365
395
 
366
- def find_illegal_ref(self) -> Optional[Tuple[ArticleRef, str]]:
396
+ @overload
397
+ def find_illegal_ref(self, gather_identical: bool) -> Optional[Tuple[ArticleRef | List[ArticleRef], str]]: ...
398
+
399
+ @overload
400
+ def find_illegal_ref(self) -> Optional[Tuple[ArticleRef, str]]: ...
401
+
402
+ def find_illegal_ref(self, gather_identical: bool = False) -> Optional[Tuple[ArticleRef | List[ArticleRef], str]]:
367
403
  """Finds the first illegal component in the outline.
368
404
 
369
405
  Returns:
@@ -374,8 +410,15 @@ class ArticleBase[T: ChapterBase](FinalizedDumpAble, AsPrompt, ABC):
374
410
  for ref in chain(component.depend_on, component.support_to):
375
411
  if not ref.deref(self):
376
412
  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"
377
- if summary:
413
+ if summary and not gather_identical:
378
414
  return ref, summary
415
+ if summary and gather_identical:
416
+ return [
417
+ identical_ref
418
+ for identical_ref in chain(self.iter_depend_on(), self.iter_support_on())
419
+ if identical_ref == ref
420
+ ], summary
421
+
379
422
  return None
380
423
 
381
424
  def finalized_dump(self) -> str:
@@ -1,223 +1,99 @@
1
1
  """ArticleEssence: Semantic fingerprint of academic paper for structured analysis."""
2
2
 
3
- from typing import List
3
+ from typing import List, Self
4
4
 
5
- from fabricatio.models.generic import Display, PrepareVectorization, ProposedAble
6
- from pydantic import BaseModel, Field
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
- """Equation significance structured in three elements:
17
- 1. Physical/conceptual meaning of the equation.
18
- 2. Role in technical workflow (e.g., derivation, optimization, or analysis).
19
- 3. Relationship to the paper's core contribution (e.g., theoretical foundation, empirical validation).
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
19
  latex_code: str
24
- """LaTeX representation following academic typesetting standards:
25
- - Must use equation environment (e.g., `equation`, `align`).
26
- - Multiline equations must align at '=' using `&`.
27
- - Include unit annotations where applicable.
28
- Example: "\\begin{equation} \\mathcal{L}_{NAS} = \\alpha \\|\\theta\\|_2 + \\beta H(p) \\end{equation}"
29
- """
20
+ """Typeset-ready notation."""
30
21
 
31
22
 
32
23
  class Figure(BaseModel):
33
- """Visual component specification for technical communication.
34
-
35
- Combines graphical assets with structured academic captioning.Extracted from the article provided
36
- """
24
+ """Visual component with academic captioning."""
37
25
 
38
26
  description: str
39
- """Figure interpretation guide containing:
40
- 1. Key visual elements mapping (e.g., axes, legends, annotations).
41
- 2. Data representation methodology (e.g., visualization type, statistical measures).
42
- 3. Connection to research findings (e.g., supports hypothesis, demonstrates performance).
43
- 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
44
31
  """
45
32
 
46
33
  figure_caption: str
47
- """Complete caption following Nature-style guidelines:
48
- 1. Brief overview statement (首句总结).
49
- 2. Technical detail layer (e.g., data sources, experimental conditions).
50
- 3. Result implication (e.g., key insights, implications for future work).
51
- 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
52
38
  """
53
39
 
54
40
  figure_serial_number: int
55
- """The Image serial number extracted from the Markdown article provided, the path usually in the form of `![](images/1.jpg)`, in this case the serial number is `1`"""
56
-
57
-
58
- class Algorithm(BaseModel):
59
- """Algorithm specification for research contributions."""
60
-
61
- title: str
62
- """Algorithm title with technical focus descriptor (e.g., 'Gradient Descent Optimization').
63
-
64
- Tip: Do not attempt to translate the original element titles when generating JSON.
65
- """
66
-
67
- description: str
68
- """Algorithm description with technical focus descriptor:
69
- - Includes input/output specifications.
70
- - Describes key steps and their purpose.
71
- - Explains its role in the research workflow.
72
- Example: "Proposed algorithm for neural architecture search. Inputs include search space constraints and training data. Outputs optimized architecture."
73
- """
74
-
75
-
76
- class Table(BaseModel):
77
- """Table specification for research contributions."""
78
-
79
- title: str
80
- """Table title with technical focus descriptor (e.g., 'Comparison of Model Performance Metrics').
81
-
82
- Tip: Do not attempt to translate the original element titles when generating JSON.
83
- """
84
-
85
- description: str
86
- """Table description with technical focus descriptor:
87
- - Includes data source and structure.
88
- - Explains key columns/rows and their significance.
89
- - Connects to research findings or hypotheses.
90
- Example: "Performance metrics for different architectures. Columns represent accuracy, F1-score, and inference time. Highlights efficiency gains of proposed method."
91
- """
41
+ """Image serial number extracted from Markdown path"""
92
42
 
93
43
 
94
44
  class Highlightings(BaseModel):
95
- """Technical showcase aggregator for research artifacts.
96
-
97
- Curates core scientific components with machine-parseable annotations.
98
- """
45
+ """Technical component aggregator."""
99
46
 
100
47
  highlighted_equations: List[Equation]
101
- """3-5 pivotal equations representing theoretical contributions:
102
- - Each equation must be wrapped in $$ for display math.
103
- - Contain at least one novel operator/symbol.
104
- - Be referenced in Methods/Results sections.
105
- Example: Equation describing proposed loss function.
106
- """
107
-
108
- highlighted_algorithms: List[Algorithm]
109
- """1-2 key algorithms demonstrating methodological contributions:
110
- - Include pseudocode or step-by-step descriptions.
111
- - Highlight innovation in computational approach.
112
- Example: Algorithm for constrained search space exploration.
113
-
114
- Tip: Do not attempt to translate the original element titles when generating JSON.
115
- """
48
+ """Equations that highlight the article's core contributions"""
116
49
 
117
50
  highlighted_figures: List[Figure]
118
- """4-6 key figures demonstrating:
119
- 1. Framework overview (1 required).
120
- 2. Quantitative results (2-3 required).
121
- 3. Ablation studies (1 optional).
122
- Each must appear in Results/Discussion chapters.
123
- Example: Figure showing architecture topology and convergence curves.
51
+ """key figures requiring:
52
+ 1. Framework overview
53
+ 2. Quantitative results
124
54
  """
125
55
 
126
- highlighted_tables: List[Table]
127
- """2-3 key tables summarizing:
128
- - Comparative analysis of methods.
129
- - Empirical results supporting claims.
130
- Example: Table comparing model performance across datasets.
131
56
 
132
- Tip: Do not attempt to translate the original element titles when generating JSON.
133
- """
134
-
135
-
136
- class ArticleEssence(ProposedAble, Display, PrepareVectorization):
137
- """ArticleEssence is a structured representation of the core elements of a scientific article."""
57
+ class ArticleEssence(ProposedAble, Display, PersistentAble, Vectorizable):
58
+ """Structured representation of a scientific article's core elements in its original language."""
138
59
 
139
- language: str = Field(...)
60
+ language: str
140
61
  """Language of the original article."""
141
62
 
142
- title: str = Field(...)
143
- """Exact title of the original article without any modification.
144
- Must be preserved precisely from the source material without:
145
- - Translation
146
- - Paraphrasing
147
- - Adding/removing words
148
- - Altering style or formatting
149
- """
63
+ title: str
64
+ """Exact title of the original article."""
150
65
 
151
66
  authors: List[str]
152
- """Original author full names exactly as they appear in the source document. No translation or paraphrasing.
153
- Extract complete list without any modifications or formatting changes."""
67
+ """Original author full names as they appear in the source document."""
154
68
 
155
69
  keywords: List[str]
156
- """Original keywords exactly as they appear in the source document. No translation or paraphrasing.
157
- Extract the complete set without modifying format or terminology."""
70
+ """Original keywords as they appear in the source document."""
158
71
 
159
72
  publication_year: int
160
- """Publication timestamp in ISO 8601 (YYYY format)."""
73
+ """Publication year in ISO 8601 (YYYY format)."""
161
74
 
162
75
  highlightings: Highlightings
163
- """Technical highlight reel containing:
164
- - Core equations (Theory)
165
- - Key algorithms (Implementation)
166
- - Critical figures (Results)
167
- - Benchmark tables (Evaluation)"""
76
+ """Technical highlights including equations, algorithms, figures, and tables."""
168
77
 
169
- domain: List[str]
170
- """Domain tags for research focus."""
171
-
172
- abstract: str = Field(...)
173
- """Abstract text with original language."""
78
+ abstract: str
79
+ """Abstract text in the original language."""
174
80
 
175
81
  core_contributions: List[str]
176
- """3-5 technical contributions using CRediT taxonomy verbs.
177
- Each item starts with action verb.
178
- Example:
179
- - 'Developed constrained NAS framework'
180
- - 'Established cross-lingual transfer metrics'"""
82
+ """Technical contributions using CRediT taxonomy verbs."""
181
83
 
182
84
  technical_novelty: List[str]
183
-
184
- """Patent-style claims with technical specificity.
185
- Format: 'A [system/method] comprising [novel components]...'
186
- Example:
187
- 'A neural architecture search system comprising:
188
- a differentiable constrained search space;
189
- multi-lingual transferability predictors...'"""
85
+ """Patent-style claims with technical specificity."""
190
86
 
191
87
  research_problems: List[str]
192
- """Problem statements as how/why questions.
193
- Example:
194
- - 'How to reduce NAS computational overhead while maintaining search diversity?'
195
- - 'Why do existing architectures fail in low-resource cross-lingual transfer?'"""
88
+ """Problem statements as how/why questions."""
196
89
 
197
90
  limitations: List[str]
198
- """Technical limitations analysis containing:
199
- 1. Constraint source (data/method/theory)
200
- 2. Impact quantification
201
- 3. Mitigation pathway
202
- Example:
203
- 'Methodology constraint: Single-objective optimization (affects 5% edge cases),
204
- mitigated through future multi-task extension'"""
205
-
206
- future_work: List[str]
207
- """Research roadmap items with 3 horizons:
208
- 1. Immediate extensions (1 year)
209
- 2. Mid-term directions (2-3 years)
210
- 3. Long-term vision (5+ years)
211
- Example:
212
- 'Short-term: Adapt framework for vision transformers (ongoing with CVPR submission)'"""
213
-
214
- impact_analysis: List[str]
215
- """Bibliometric impact projections:
216
- - Expected citation counts (next 3 years)
217
- - Target application domains
218
- - Standard adoption potential
219
- Example:
220
- 'Predicted 150+ citations via integration into MMEngine (Alibaba OpenMMLab)'"""
221
-
222
- def _prepare_vectorization_inner(self) -> str:
223
- return self.model_dump_json()
91
+ """Technical limitations analysis."""
92
+
93
+ bibtex_cite_key: str
94
+ """Bibtex cite key of the original article."""
95
+
96
+ def update_cite_key(self, new_cite_key: str) -> Self:
97
+ """Update the bibtex_cite_key of the article."""
98
+ self.bibtex_cite_key = new_cite_key
99
+ return self
@@ -8,6 +8,7 @@ from fabricatio.models.extra.article_base import (
8
8
  ArticleBase,
9
9
  ArticleOutlineBase,
10
10
  ChapterBase,
11
+ Patch,
11
12
  SectionBase,
12
13
  SubSectionBase,
13
14
  )
@@ -15,7 +16,7 @@ from fabricatio.models.extra.article_outline import (
15
16
  ArticleOutline,
16
17
  )
17
18
  from fabricatio.models.generic import CensoredAble, Display, PersistentAble, WithRef
18
- from fabricatio.models.utils import ok
19
+ from fabricatio.utils import ok
19
20
 
20
21
 
21
22
  class Paragraph(CensoredAble):
@@ -31,6 +32,10 @@ class Paragraph(CensoredAble):
31
32
  """The actual content of the paragraph, represented as a string."""
32
33
 
33
34
 
35
+ class ArticleParagraphPatch(Patch[Paragraph]):
36
+ """Patch for `Paragraph` list of `ArticleSubsection`."""
37
+
38
+
34
39
  class ArticleSubsection(SubSectionBase):
35
40
  """Atomic argumentative unit with technical specificity."""
36
41
 
@@ -29,5 +29,23 @@ class ArticleProposal(CensoredAble, Display, WithRef[str], AsPrompt, PersistentA
29
29
  research_aim: List[str]
30
30
  """A list of primary research objectives that the paper seeks to achieve."""
31
31
 
32
+ literature_review: List[str]
33
+ """A list of key references and literature that support the research context and background."""
34
+
35
+ expected_outcomes: List[str]
36
+ """A list of anticipated results or contributions that the research aims to achieve."""
37
+
38
+ keywords: List[str]
39
+ """A list of keywords that represent the main topics and focus areas of the research."""
40
+
41
+ abstract: str
42
+ """A concise summary of the research proposal, outlining the main points and objectives."""
43
+
44
+ min_word_count: int
45
+ """The minimum number of words required for the research proposal."""
46
+
32
47
  def _as_prompt_inner(self) -> Dict[str, str]:
33
- return {"ArticleBriefing": self.referenced, "ArticleProposal": self.display()}
48
+ return {
49
+ "ArticleBriefing": self.referenced,
50
+ "ArticleProposal": self.display(),
51
+ }
@@ -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."""