fabricatio 0.2.7.dev4__cp312-cp312-win_amd64.whl → 0.2.8__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 (49) hide show
  1. fabricatio/__init__.py +4 -11
  2. fabricatio/actions/article.py +226 -92
  3. fabricatio/actions/article_rag.py +86 -21
  4. fabricatio/actions/output.py +71 -3
  5. fabricatio/actions/rag.py +3 -3
  6. fabricatio/actions/rules.py +39 -0
  7. fabricatio/capabilities/advanced_judge.py +23 -0
  8. fabricatio/capabilities/censor.py +90 -0
  9. fabricatio/capabilities/check.py +195 -0
  10. fabricatio/capabilities/correct.py +160 -96
  11. fabricatio/capabilities/propose.py +20 -4
  12. fabricatio/capabilities/rag.py +5 -4
  13. fabricatio/capabilities/rating.py +68 -23
  14. fabricatio/capabilities/review.py +21 -190
  15. fabricatio/capabilities/task.py +9 -10
  16. fabricatio/config.py +11 -3
  17. fabricatio/fs/curd.py +4 -0
  18. fabricatio/models/action.py +24 -10
  19. fabricatio/models/adv_kwargs_types.py +25 -0
  20. fabricatio/models/extra/__init__.py +1 -0
  21. fabricatio/models/extra/advanced_judge.py +32 -0
  22. fabricatio/models/extra/article_base.py +324 -89
  23. fabricatio/models/extra/article_essence.py +49 -176
  24. fabricatio/models/extra/article_main.py +48 -127
  25. fabricatio/models/extra/article_outline.py +12 -152
  26. fabricatio/models/extra/article_proposal.py +29 -13
  27. fabricatio/models/extra/patches.py +7 -0
  28. fabricatio/models/extra/problem.py +153 -0
  29. fabricatio/models/extra/rule.py +65 -0
  30. fabricatio/models/generic.py +360 -88
  31. fabricatio/models/kwargs_types.py +23 -17
  32. fabricatio/models/role.py +4 -1
  33. fabricatio/models/task.py +1 -1
  34. fabricatio/models/tool.py +149 -14
  35. fabricatio/models/usages.py +61 -47
  36. fabricatio/models/utils.py +0 -46
  37. fabricatio/parser.py +7 -8
  38. fabricatio/rust.cp312-win_amd64.pyd +0 -0
  39. fabricatio/{_rust.pyi → rust.pyi} +50 -0
  40. fabricatio/{_rust_instances.py → rust_instances.py} +1 -1
  41. fabricatio/utils.py +54 -0
  42. fabricatio-0.2.8.data/scripts/tdown.exe +0 -0
  43. {fabricatio-0.2.7.dev4.dist-info → fabricatio-0.2.8.dist-info}/METADATA +2 -1
  44. fabricatio-0.2.8.dist-info/RECORD +58 -0
  45. fabricatio/_rust.cp312-win_amd64.pyd +0 -0
  46. fabricatio-0.2.7.dev4.data/scripts/tdown.exe +0 -0
  47. fabricatio-0.2.7.dev4.dist-info/RECORD +0 -47
  48. {fabricatio-0.2.7.dev4.dist-info → fabricatio-0.2.8.dist-info}/WHEEL +0 -0
  49. {fabricatio-0.2.7.dev4.dist-info → fabricatio-0.2.8.dist-info}/licenses/LICENSE +0 -0
@@ -1,30 +1,27 @@
1
1
  """A module containing the ArticleOutline class, which represents the outline of an academic paper."""
2
2
 
3
- from typing import Generator, List, Optional, Tuple, Union
3
+ from typing import Dict
4
4
 
5
- import regex
6
5
  from fabricatio.models.extra.article_base import (
7
6
  ArticleBase,
8
- ArticleOutlineBase,
9
7
  ChapterBase,
10
8
  SectionBase,
11
9
  SubSectionBase,
12
10
  )
13
11
  from fabricatio.models.extra.article_proposal import ArticleProposal
14
12
  from fabricatio.models.generic import CensoredAble, Display, PersistentAble, WithRef
15
- from fabricatio.models.utils import ok
16
13
 
17
14
 
18
- class ArticleSubsectionOutline(ArticleOutlineBase, SubSectionBase):
15
+ class ArticleSubsectionOutline(SubSectionBase):
19
16
  """Atomic research component specification for academic paper generation."""
20
17
 
21
18
 
22
- class ArticleSectionOutline(ArticleOutlineBase, SectionBase[ArticleSubsectionOutline]):
23
- """A slightly more detailed research component specification for academic paper generation."""
19
+ class ArticleSectionOutline(SectionBase[ArticleSubsectionOutline]):
20
+ """A slightly more detailed research component specification for academic paper generation, Must contain subsections."""
24
21
 
25
22
 
26
- class ArticleChapterOutline(ArticleOutlineBase, ChapterBase[ArticleSectionOutline]):
27
- """Macro-structural unit implementing standard academic paper organization."""
23
+ class ArticleChapterOutline(ChapterBase[ArticleSectionOutline]):
24
+ """Macro-structural unit implementing standard academic paper organization. Must contain sections."""
28
25
 
29
26
 
30
27
  class ArticleOutline(
@@ -34,148 +31,11 @@ class ArticleOutline(
34
31
  PersistentAble,
35
32
  ArticleBase[ArticleChapterOutline],
36
33
  ):
37
- """Complete academic paper blueprint with hierarchical validation."""
34
+ """Outline of an academic paper, containing chapters, sections, subsections."""
38
35
 
39
- abstract: str
40
- """The abstract is a concise summary of the academic paper's main findings."""
41
-
42
- prospect: str
43
- """Consolidated research statement with four pillars:
44
- 1. Problem Identification: Current limitations
45
- 2. Methodological Response: Technical approach
46
- 3. Empirical Validation: Evaluation strategy
47
- 4. Scholarly Impact: Field contributions
48
- """
49
-
50
- title: str
51
- """Title of the academic paper."""
52
-
53
- language: str
54
- """Written language of the article. SHALL be aligned to the language of the article proposal provided."""
55
-
56
- def finalized_dump(self) -> str:
57
- """Generates standardized hierarchical markup for academic publishing systems.
58
-
59
- Implements ACL 2024 outline conventions with four-level structure:
60
- = Chapter Title (Level 1)
61
- == Section Title (Level 2)
62
- === Subsection Title (Level 3)
63
- ==== Subsubsection Title (Level 4)
64
-
65
- Returns:
66
- str: Strictly formatted outline with academic sectioning
67
-
68
- Example:
69
- = Methodology
70
- == Neural Architecture Search Framework
71
- === Differentiable Search Space
72
- ==== Constrained Optimization Parameters
73
- === Implementation Details
74
- == Evaluation Protocol
75
- """
76
- lines: List[str] = []
77
- for i, chapter in enumerate(self.chapters, 1):
78
- lines.append(f"= Chapter {i}: {chapter.title}")
79
- for j, section in enumerate(chapter.sections, 1):
80
- lines.append(f"== {i}.{j} {section.title}")
81
- for k, subsection in enumerate(section.subsections, 1):
82
- lines.append(f"=== {i}.{j}.{k} {subsection.title}")
83
- return "\n".join(lines)
84
-
85
- def iter_dfs(self) -> Generator[ArticleOutlineBase, None, None]:
86
- """Iterates through the article outline in a depth-first manner.
87
-
88
- Returns:
89
- ArticleOutlineBase: Each component in the article outline.
90
- """
91
- for chapter in self.chapters:
92
- for section in chapter.sections:
93
- yield from section.subsections
94
- yield section
95
- yield chapter
96
-
97
- def resolve_ref_error(self) -> str:
98
- """Resolve reference errors in the article outline.
99
-
100
- Returns:
101
- str: Error message indicating reference errors in the article outline.
102
-
103
- Notes:
104
- This function is designed to find all invalid `ArticleRef` objs in `depend_on` and `support_to` fields, which will be added to the final error summary.
105
- """
106
- summary = ""
107
- for component in self.iter_dfs():
108
- for ref in component.depend_on:
109
- if not ref.deref(self):
110
- summary += f"Invalid internal reference in {component.__class__.__name__} titled `{component.title}` at `depend_on` field, because the referred {ref.referring_type} is not exists within the article, see the original obj dump: {ref.model_dump()}\n"
111
- for ref in component.support_to:
112
- if not ref.deref(self):
113
- summary += f"Invalid internal reference in {component.__class__.__name__} titled `{component.title}` at `support_to` field, because the referred {ref.referring_type} is not exists within the article, see the original obj dump: {ref.model_dump()}\n"
114
-
115
- return summary
116
-
117
- @classmethod
118
- def from_typst_code(
119
- cls, typst_code: str, title: str = "", article_language: str = "en", prospect: str = "", abstract: str = ""
120
- ) -> "ArticleOutline":
121
- """Parses a Typst code string and creates an ArticleOutline instance."""
122
- self = cls(language=article_language, prospect=prospect, abstract=abstract, chapters=[], title=title)
123
- stack = [self] # 根节点为ArticleOutline实例
124
-
125
- for line in typst_code.splitlines():
126
- parsed = cls._parse_line(line)
127
- if not parsed:
128
- continue
129
- level, title = parsed
130
- cls._adjust_stack(stack, level)
131
- parent = stack[-1]
132
- component = cls._create_component(level, title)
133
- cls._add_to_parent(parent, component, level)
134
- stack.append(component)
135
-
136
- return self
137
-
138
- @classmethod
139
- def _parse_line(cls, line: str) -> Optional[Tuple[int, str]]:
140
- stripped = line.strip()
141
- if not stripped.startswith("="):
142
- return None
143
- match = regex.match(r"^(\=+)(.*)", stripped)
144
- if not match:
145
- return None
146
- eqs, title_part = match.groups()
147
- return len(eqs), title_part.strip()
148
-
149
- @classmethod
150
- def _adjust_stack(cls, stack: List[object], target_level: int) -> None:
151
- while len(stack) > target_level:
152
- stack.pop()
153
-
154
- @classmethod
155
- def _create_component(cls, level: int, title: str) -> ArticleOutlineBase:
156
- default_kwargs = {
157
- "writing_aim": [],
158
- "depend_on": [],
159
- "support_to": [],
160
- "description": [],
36
+ def _as_prompt_inner(self) -> Dict[str, str]:
37
+ return {
38
+ "Original Article Briefing": self.referenced.referenced,
39
+ "Original Article Proposal": self.referenced.display(),
40
+ "Original Article Outline": self.display(),
161
41
  }
162
- component_map = {
163
- 1: lambda: ArticleChapterOutline(title=title, sections=[], **default_kwargs),
164
- 2: lambda: ArticleSectionOutline(title=title, subsections=[], **default_kwargs),
165
- 3: lambda: ArticleSubsectionOutline(title=title, **default_kwargs),
166
- }
167
- return ok(component_map.get(level, lambda: None)(), "Invalid level")
168
-
169
- @classmethod
170
- def _add_to_parent(
171
- cls,
172
- parent: Union["ArticleOutline", ArticleChapterOutline, ArticleSectionOutline],
173
- component: ArticleOutlineBase,
174
- level: int,
175
- ) -> None:
176
- if level == 1 and isinstance(component, ArticleChapterOutline):
177
- parent.chapters.append(component)
178
- elif level == 2 and isinstance(component, ArticleSectionOutline): # noqa: PLR2004
179
- parent.sections.append(component)
180
- elif level == 3 and isinstance(component, ArticleSubsectionOutline): # noqa: PLR2004
181
- parent.subsections.append(component)
@@ -11,25 +11,41 @@ class ArticleProposal(CensoredAble, Display, WithRef[str], AsPrompt, PersistentA
11
11
  Guides LLM in generating comprehensive research proposals with clearly defined components.
12
12
  """
13
13
 
14
+ language: str
15
+ """The language in which the article is written. This should align with the language specified in the article briefing."""
16
+
17
+ title: str
18
+ """The title of the academic paper, formatted in Title Case."""
19
+
20
+ focused_problem: List[str]
21
+ """A list of specific research problems or questions that the paper aims to address."""
22
+
14
23
  technical_approaches: List[str]
15
- """Technical approaches"""
24
+ """A list of technical approaches or methodologies used to solve the research problems."""
16
25
 
17
26
  research_methods: List[str]
18
- """Methodological components (list of techniques/tools).
19
- Example: ['Differentiable architecture search', 'Transformer-based search space', 'Multi-lingual perplexity evaluation']"""
27
+ """A list of methodological components, including techniques and tools utilized in the research."""
20
28
 
21
29
  research_aim: List[str]
22
- """Primary research objectives (list of 2-4 measurable goals).
23
- Example: ['Develop parameter-efficient NAS framework', 'Establish cross-lingual architecture transfer metrics']"""
30
+ """A list of primary research objectives that the paper seeks to achieve."""
24
31
 
25
- focused_problem: List[str]
26
- """Specific research problem(s) or question(s) addressed (list of 1-3 concise statements).
27
- Example: ['NAS computational overhead in low-resource settings', 'Architecture transferability across language pairs']"""
32
+ literature_review: List[str]
33
+ """A list of key references and literature that support the research context and background."""
28
34
 
29
- title: str
30
- """Paper title in academic style (Title Case, 8-15 words). Example: 'Exploring Neural Architecture Search for Low-Resource Machine Translation'"""
31
- language: str
32
- """Written language of the article. SHALL be aligned to the language of the article briefing provided."""
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."""
33
46
 
34
47
  def _as_prompt_inner(self) -> Dict[str, str]:
35
- return {"ArticleBriefing": self.referenced, "ArticleProposal": self.display()}
48
+ return {
49
+ "ArticleBriefing": self.referenced,
50
+ "ArticleProposal": self.display(),
51
+ }
@@ -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,65 @@
1
+ """A module containing classes related to rule sets and rules.
2
+
3
+ This module provides the `Rule` and `RuleSet` classes, which are used to define and manage
4
+ individual rules and collections of rules, respectively. These classes are designed to
5
+ facilitate the creation, organization, and application of rules in various contexts,
6
+ ensuring clarity, consistency, and enforceability. The module supports detailed
7
+ descriptions, examples, and metadata for each rule and rule set, making it suitable for
8
+ complex rule management systems.
9
+ """
10
+
11
+
12
+ from typing import List
13
+
14
+ from fabricatio.models.generic import PersistentAble, SketchedAble, WithBriefing
15
+
16
+
17
+ class Rule(WithBriefing, SketchedAble):
18
+ """Represents a rule or guideline for a specific topic.
19
+
20
+ The `Rule` class encapsulates a single rule, providing detailed information about its
21
+ purpose, scope, and application. It includes fields for a comprehensive description,
22
+ examples of violations, and examples of compliance. This class is designed to ensure
23
+ that rules are clearly defined, well-documented, and easy to understand and enforce.
24
+ """
25
+
26
+ description: str
27
+ """A comprehensive description of the rule, including its purpose, scope, and context.
28
+ This should clearly explain what the rule is about, why it exists, and in what situations
29
+ it applies. The description should be detailed enough to provide full understanding of
30
+ the rule's intent and application."""
31
+
32
+ violation_examples: List[str]
33
+ """A list of concrete examples demonstrating violations of this rule. Each example should
34
+ be a clear scenario or case that illustrates how the rule can be broken, including the
35
+ context, actions, and consequences of the violation. These examples should help in
36
+ understanding the boundaries of the rule."""
37
+
38
+ compliance_examples: List[str]
39
+ """A list of concrete examples demonstrating proper compliance with this rule. Each example
40
+ should be a clear scenario or case that illustrates how to correctly follow the rule,
41
+ including the context, actions, and positive outcomes of compliance. These examples should
42
+ serve as practical guidance for implementing the rule correctly."""
43
+
44
+
45
+ class RuleSet(SketchedAble, PersistentAble, WithBriefing):
46
+ """Represents a collection of rules and guidelines for a particular topic.
47
+
48
+ The `RuleSet` class is used to group related rules into a coherent set, providing a
49
+ structured way to manage and apply multiple rules. It includes a description of the
50
+ overall purpose and scope of the rule set, as well as a list of individual rules. This
51
+ class is designed to ensure that rule sets are well-organized, consistent, and easy to
52
+ navigate and enforce.
53
+ """
54
+
55
+ description: str
56
+ """A comprehensive description of the rule set, including its overall purpose, scope, and
57
+ context. This should explain why this collection of rules exists, what domain or topic it
58
+ covers, and how the rules within the set are related to each other. The description should
59
+ provide a clear understanding of the rule set's intent and application."""
60
+
61
+ rules: List[Rule]
62
+ """The collection of rules and guidelines contained in this rule set. Each rule should be
63
+ a well-defined, specific guideline that contributes to the overall purpose of the rule set.
64
+ The rules should be logically organized and consistent with each other, forming a coherent
65
+ framework for the topic or domain covered by the rule set."""