fabricatio 0.2.7.dev5__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.
- fabricatio/__init__.py +4 -11
- fabricatio/actions/article.py +219 -92
- fabricatio/actions/article_rag.py +86 -21
- fabricatio/actions/output.py +71 -3
- fabricatio/actions/rag.py +3 -3
- fabricatio/actions/rules.py +39 -0
- fabricatio/capabilities/advanced_judge.py +23 -0
- fabricatio/capabilities/censor.py +90 -0
- fabricatio/capabilities/check.py +195 -0
- fabricatio/capabilities/correct.py +160 -96
- fabricatio/capabilities/propose.py +20 -4
- fabricatio/capabilities/rag.py +5 -4
- fabricatio/capabilities/rating.py +68 -23
- fabricatio/capabilities/review.py +21 -190
- fabricatio/capabilities/task.py +9 -10
- fabricatio/config.py +11 -3
- fabricatio/fs/curd.py +4 -0
- fabricatio/models/action.py +24 -10
- fabricatio/models/adv_kwargs_types.py +25 -0
- fabricatio/models/extra/__init__.py +1 -0
- fabricatio/models/extra/advanced_judge.py +32 -0
- fabricatio/models/extra/article_base.py +222 -86
- fabricatio/models/extra/article_essence.py +49 -176
- fabricatio/models/extra/article_main.py +35 -51
- fabricatio/models/extra/article_outline.py +10 -156
- fabricatio/models/extra/article_proposal.py +29 -13
- fabricatio/models/extra/patches.py +7 -0
- fabricatio/models/extra/problem.py +153 -0
- fabricatio/models/extra/rule.py +65 -0
- fabricatio/models/generic.py +311 -94
- fabricatio/models/kwargs_types.py +23 -17
- fabricatio/models/role.py +4 -1
- fabricatio/models/task.py +1 -1
- fabricatio/models/tool.py +149 -14
- fabricatio/models/usages.py +61 -47
- fabricatio/models/utils.py +0 -46
- fabricatio/parser.py +7 -8
- fabricatio/rust.cp312-win_amd64.pyd +0 -0
- fabricatio/{_rust.pyi → rust.pyi} +50 -0
- fabricatio/{_rust_instances.py → rust_instances.py} +1 -1
- fabricatio/utils.py +54 -0
- fabricatio-0.2.8.data/scripts/tdown.exe +0 -0
- {fabricatio-0.2.7.dev5.dist-info → fabricatio-0.2.8.dist-info}/METADATA +2 -1
- fabricatio-0.2.8.dist-info/RECORD +58 -0
- fabricatio/_rust.cp312-win_amd64.pyd +0 -0
- fabricatio-0.2.7.dev5.data/scripts/tdown.exe +0 -0
- fabricatio-0.2.7.dev5.dist-info/RECORD +0 -47
- {fabricatio-0.2.7.dev5.dist-info → fabricatio-0.2.8.dist-info}/WHEEL +0 -0
- {fabricatio-0.2.7.dev5.dist-info → fabricatio-0.2.8.dist-info}/licenses/LICENSE +0 -0
@@ -1,226 +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,
|
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
19
|
latex_code: str
|
24
|
-
"""
|
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
|
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
|
-
"""
|
40
|
-
1.
|
41
|
-
2. Data representation
|
42
|
-
3.
|
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
|
-
"""
|
48
|
-
1.
|
49
|
-
2. Technical
|
50
|
-
3. Result
|
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
|
-
"""
|
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
|
96
|
-
|
97
|
-
Curates core scientific components with machine-parseable annotations.
|
98
|
-
"""
|
45
|
+
"""Technical component aggregator."""
|
99
46
|
|
100
47
|
highlighted_equations: List[Equation]
|
101
|
-
"""
|
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
|
-
"""
|
119
|
-
1. Framework overview
|
120
|
-
2. Quantitative results
|
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
|
-
|
132
|
-
Tip: Do not attempt to translate the original element titles when generating JSON.
|
133
|
-
"""
|
134
56
|
|
57
|
+
class ArticleEssence(ProposedAble, Display, PersistentAble, Vectorizable):
|
58
|
+
"""Structured representation of a scientific article's core elements in its original language."""
|
135
59
|
|
136
|
-
|
137
|
-
"""
|
60
|
+
language: str
|
61
|
+
"""Language of the original article."""
|
138
62
|
|
139
|
-
|
140
|
-
"""
|
141
|
-
|
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 names
|
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
|
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
|
73
|
+
"""Publication year in ISO 8601 (YYYY format)."""
|
161
74
|
|
162
75
|
highlightings: Highlightings
|
163
|
-
"""Technical
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
- Benchmark tables (Evaluation)"""
|
168
|
-
|
169
|
-
domain: List[str]
|
170
|
-
"""Domain tags for research focus."""
|
171
|
-
|
172
|
-
abstract: str = Field(...)
|
173
|
-
"""Three-paragraph structured abstract:
|
174
|
-
Paragraph 1: Problem & Motivation (2-3 sentences)
|
175
|
-
Paragraph 2: Methodology & Innovations (3-4 sentences)
|
176
|
-
Paragraph 3: Results & Impact (2-3 sentences)
|
177
|
-
Total length: 150-250 words"""
|
76
|
+
"""Technical highlights including equations, algorithms, figures, and tables."""
|
77
|
+
|
78
|
+
abstract: str
|
79
|
+
"""Abstract text in the original language."""
|
178
80
|
|
179
81
|
core_contributions: List[str]
|
180
|
-
"""
|
181
|
-
Each item starts with action verb.
|
182
|
-
Example:
|
183
|
-
- 'Developed constrained NAS framework'
|
184
|
-
- 'Established cross-lingual transfer metrics'"""
|
82
|
+
"""Technical contributions using CRediT taxonomy verbs."""
|
185
83
|
|
186
84
|
technical_novelty: List[str]
|
187
|
-
"""Patent-style claims with technical specificity.
|
188
|
-
Format: 'A [system/method] comprising [novel components]...'
|
189
|
-
Example:
|
190
|
-
'A neural architecture search system comprising:
|
191
|
-
a differentiable constrained search space;
|
192
|
-
multi-lingual transferability predictors...'"""
|
85
|
+
"""Patent-style claims with technical specificity."""
|
193
86
|
|
194
87
|
research_problems: List[str]
|
195
|
-
"""Problem statements as how/why questions.
|
196
|
-
Example:
|
197
|
-
- 'How to reduce NAS computational overhead while maintaining search diversity?'
|
198
|
-
- 'Why do existing architectures fail in low-resource cross-lingual transfer?'"""
|
88
|
+
"""Problem statements as how/why questions."""
|
199
89
|
|
200
90
|
limitations: List[str]
|
201
|
-
"""Technical limitations analysis
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
"""Research roadmap items with 3 horizons:
|
211
|
-
1. Immediate extensions (1 year)
|
212
|
-
2. Mid-term directions (2-3 years)
|
213
|
-
3. Long-term vision (5+ years)
|
214
|
-
Example:
|
215
|
-
'Short-term: Adapt framework for vision transformers (ongoing with CVPR submission)'"""
|
216
|
-
|
217
|
-
impact_analysis: List[str]
|
218
|
-
"""Bibliometric impact projections:
|
219
|
-
- Expected citation counts (next 3 years)
|
220
|
-
- Target application domains
|
221
|
-
- Standard adoption potential
|
222
|
-
Example:
|
223
|
-
'Predicted 150+ citations via integration into MMEngine (Alibaba OpenMMLab)'"""
|
224
|
-
|
225
|
-
def _prepare_vectorization_inner(self) -> str:
|
226
|
-
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
|
@@ -1,13 +1,12 @@
|
|
1
1
|
"""ArticleBase and ArticleSubsection classes for managing hierarchical document components."""
|
2
2
|
|
3
3
|
from itertools import chain
|
4
|
-
from typing import Generator, List, Self, Tuple, override
|
4
|
+
from typing import Dict, Generator, List, Self, Tuple, override
|
5
5
|
|
6
6
|
from fabricatio.journal import logger
|
7
7
|
from fabricatio.models.extra.article_base import (
|
8
8
|
ArticleBase,
|
9
9
|
ArticleOutlineBase,
|
10
|
-
ArticleRef,
|
11
10
|
ChapterBase,
|
12
11
|
SectionBase,
|
13
12
|
SubSectionBase,
|
@@ -15,8 +14,8 @@ from fabricatio.models.extra.article_base import (
|
|
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):
|
@@ -28,21 +27,30 @@ class Paragraph(CensoredAble):
|
|
28
27
|
writing_aim: List[str]
|
29
28
|
"""Specific communicative objectives for this paragraph's content."""
|
30
29
|
|
31
|
-
|
32
|
-
"""
|
30
|
+
content: str
|
31
|
+
"""The actual content of the paragraph, represented as a string."""
|
33
32
|
|
34
33
|
|
35
|
-
class
|
34
|
+
class ArticleParagraphSequencePatch(SequencePatch[Paragraph]):
|
35
|
+
"""Patch for `Paragraph` list of `ArticleSubsection`."""
|
36
|
+
|
37
|
+
|
38
|
+
class ArticleSubsection(SubSectionBase):
|
36
39
|
"""Atomic argumentative unit with technical specificity."""
|
37
40
|
|
38
41
|
paragraphs: List[Paragraph]
|
39
42
|
"""List of Paragraph objects containing the content of the subsection."""
|
40
43
|
|
44
|
+
def introspect(self) -> str:
|
45
|
+
"""Introspects the subsection and returns a message if it has no paragraphs."""
|
46
|
+
if len(self.paragraphs) == 0:
|
47
|
+
return f"`{self.__class__.__name__}` titled `{self.title}` have no paragraphs, to achieve the goal of `{self.writing_aim}`."
|
48
|
+
return ""
|
49
|
+
|
41
50
|
def update_from_inner(self, other: Self) -> Self:
|
42
51
|
"""Updates the current instance with the attributes of another instance."""
|
43
52
|
logger.debug(f"Updating SubSection {self.title}")
|
44
|
-
|
45
|
-
ArticleOutlineBase.update_from(self, other)
|
53
|
+
super().update_from_inner(other)
|
46
54
|
self.paragraphs.clear()
|
47
55
|
self.paragraphs.extend(other.paragraphs)
|
48
56
|
return self
|
@@ -53,19 +61,17 @@ class ArticleSubsection(ArticleOutlineBase, SubSectionBase):
|
|
53
61
|
Returns:
|
54
62
|
str: Typst code snippet for rendering.
|
55
63
|
"""
|
56
|
-
return f"=== {self.title}\n" + "\n\n".join(
|
64
|
+
return f"=== {self.title}\n" + "\n\n".join(p.content for p in self.paragraphs)
|
57
65
|
|
58
66
|
|
59
|
-
class ArticleSection(
|
67
|
+
class ArticleSection(SectionBase[ArticleSubsection]):
|
60
68
|
"""Atomic argumentative unit with high-level specificity."""
|
61
69
|
|
62
70
|
|
63
|
-
|
64
|
-
class ArticleChapter(ArticleOutlineBase, ChapterBase[ArticleSection]):
|
71
|
+
class ArticleChapter(ChapterBase[ArticleSection]):
|
65
72
|
"""Thematic progression implementing research function."""
|
66
73
|
|
67
74
|
|
68
|
-
|
69
75
|
class Article(
|
70
76
|
Display,
|
71
77
|
CensoredAble,
|
@@ -79,22 +85,17 @@ class Article(
|
|
79
85
|
aiming to provide a comprehensive model for academic papers.
|
80
86
|
"""
|
81
87
|
|
82
|
-
|
83
|
-
|
88
|
+
def _as_prompt_inner(self) -> Dict[str, str]:
|
89
|
+
return {
|
90
|
+
"Original Article Briefing": self.referenced.referenced.referenced,
|
91
|
+
"Original Article Proposal": self.referenced.referenced.display(),
|
92
|
+
"Original Article Outline": self.referenced.display(),
|
93
|
+
"Original Article": self.display(),
|
94
|
+
}
|
84
95
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
language: str
|
89
|
-
"""Written language of the article. SHALL be aligned to the language of the article outline provided."""
|
90
|
-
|
91
|
-
def finalized_dump(self) -> str:
|
92
|
-
"""Exports the article in `typst` format.
|
93
|
-
|
94
|
-
Returns:
|
95
|
-
str: Strictly formatted outline with typst formatting.
|
96
|
-
"""
|
97
|
-
return "\n\n".join(c.to_typst_code() for c in self.chapters)
|
96
|
+
@override
|
97
|
+
def iter_subsections(self) -> Generator[Tuple[ArticleChapter, ArticleSection, ArticleSubsection], None, None]:
|
98
|
+
return super().iter_subsections()
|
98
99
|
|
99
100
|
@classmethod
|
100
101
|
def from_outline(cls, outline: ArticleOutline) -> "Article":
|
@@ -107,7 +108,7 @@ class Article(
|
|
107
108
|
Article: The generated article.
|
108
109
|
"""
|
109
110
|
# Set the title from the outline
|
110
|
-
article = Article(**outline.model_dump(
|
111
|
+
article = Article(**outline.model_dump(exclude={"chapters"}), chapters=[])
|
111
112
|
|
112
113
|
for chapter in outline.chapters:
|
113
114
|
# Create a new chapter
|
@@ -132,33 +133,16 @@ class Article(
|
|
132
133
|
article.chapters.append(article_chapter)
|
133
134
|
return article
|
134
135
|
|
135
|
-
@override
|
136
|
-
def iter_dfs(
|
137
|
-
self,
|
138
|
-
) -> Generator[ArticleChapter | ArticleSection | ArticleSubsection, None, None]:
|
139
|
-
return super().iter_dfs()
|
140
|
-
|
141
|
-
def deref(self, ref: ArticleRef) -> ArticleOutlineBase:
|
142
|
-
"""Resolves a reference to the corresponding section or subsection in the article.
|
143
|
-
|
144
|
-
Args:
|
145
|
-
ref (ArticleRef): The reference to resolve.
|
146
|
-
|
147
|
-
Returns:
|
148
|
-
ArticleOutlineBase: The corresponding section or subsection.
|
149
|
-
"""
|
150
|
-
return ok(ref.deref(self), f"{ref} not found in {self.title}")
|
151
|
-
|
152
136
|
def gather_dependencies(self, article: ArticleOutlineBase) -> List[ArticleOutlineBase]:
|
153
137
|
"""Gathers dependencies for all sections and subsections in the article.
|
154
138
|
|
155
139
|
This method should be called after the article is fully constructed.
|
156
140
|
"""
|
157
|
-
depends = [
|
141
|
+
depends = [ok(a.deref(self)) for a in article.depend_on]
|
158
142
|
|
159
143
|
supports = []
|
160
|
-
for a in self.
|
161
|
-
if article in {
|
144
|
+
for a in self.iter_dfs_rev():
|
145
|
+
if article in {ok(b.deref(self)) for b in a.support_to}:
|
162
146
|
supports.append(a)
|
163
147
|
|
164
148
|
return list(set(depends + supports))
|
@@ -220,7 +204,7 @@ class Article(
|
|
220
204
|
if all((not chapter, not section, not subsection)):
|
221
205
|
raise ValueError("At least one of chapter, section, or subsection must be True.")
|
222
206
|
|
223
|
-
for component in self.
|
207
|
+
for component in self.iter_dfs_rev():
|
224
208
|
if not chapter and isinstance(component, ArticleChapter):
|
225
209
|
continue
|
226
210
|
if not section and isinstance(component, ArticleSection):
|
@@ -1,45 +1,28 @@
|
|
1
1
|
"""A module containing the ArticleOutline class, which represents the outline of an academic paper."""
|
2
2
|
|
3
|
-
from typing import
|
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(
|
15
|
+
class ArticleSubsectionOutline(SubSectionBase):
|
19
16
|
"""Atomic research component specification for academic paper generation."""
|
20
17
|
|
21
18
|
|
22
|
-
|
23
|
-
class ArticleSectionOutline(ArticleOutlineBase, SectionBase[ArticleSubsectionOutline]):
|
19
|
+
class ArticleSectionOutline(SectionBase[ArticleSubsectionOutline]):
|
24
20
|
"""A slightly more detailed research component specification for academic paper generation, Must contain subsections."""
|
25
21
|
|
26
22
|
|
27
|
-
|
28
|
-
"""Updates the current instance with the attributes of another instance."""
|
29
|
-
super().update_from_inner(other)
|
30
|
-
super(ArticleOutlineBase, self).update_from_inner(other)
|
31
|
-
return self
|
32
|
-
|
33
|
-
|
34
|
-
class ArticleChapterOutline(ArticleOutlineBase, ChapterBase[ArticleSectionOutline]):
|
23
|
+
class ArticleChapterOutline(ChapterBase[ArticleSectionOutline]):
|
35
24
|
"""Macro-structural unit implementing standard academic paper organization. Must contain sections."""
|
36
25
|
|
37
|
-
def update_from_inner(self, other: Self) -> Self:
|
38
|
-
"""Updates the current instance with the attributes of another instance."""
|
39
|
-
super().update_from_inner(other)
|
40
|
-
super(ArticleOutlineBase, self).update_from_inner(other)
|
41
|
-
return self
|
42
|
-
|
43
26
|
|
44
27
|
class ArticleOutline(
|
45
28
|
Display,
|
@@ -48,140 +31,11 @@ class ArticleOutline(
|
|
48
31
|
PersistentAble,
|
49
32
|
ArticleBase[ArticleChapterOutline],
|
50
33
|
):
|
51
|
-
"""
|
52
|
-
|
53
|
-
abstract: str
|
54
|
-
"""The abstract is a concise summary of the academic paper's main findings."""
|
55
|
-
|
56
|
-
prospect: str
|
57
|
-
"""Consolidated research statement with four pillars:
|
58
|
-
1. Problem Identification: Current limitations
|
59
|
-
2. Methodological Response: Technical approach
|
60
|
-
3. Empirical Validation: Evaluation strategy
|
61
|
-
4. Scholarly Impact: Field contributions
|
62
|
-
"""
|
63
|
-
|
64
|
-
title: str
|
65
|
-
"""Title of the academic paper."""
|
66
|
-
|
67
|
-
language: str
|
68
|
-
"""Written language of the article. SHALL be aligned to the language of the article proposal provided."""
|
69
|
-
|
70
|
-
def finalized_dump(self) -> str:
|
71
|
-
"""Generates standardized hierarchical markup for academic publishing systems.
|
72
|
-
|
73
|
-
Implements ACL 2024 outline conventions with four-level structure:
|
74
|
-
= Chapter Title (Level 1)
|
75
|
-
== Section Title (Level 2)
|
76
|
-
=== Subsection Title (Level 3)
|
77
|
-
==== Subsubsection Title (Level 4)
|
78
|
-
|
79
|
-
Returns:
|
80
|
-
str: Strictly formatted outline with academic sectioning
|
34
|
+
"""Outline of an academic paper, containing chapters, sections, subsections."""
|
81
35
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
=== Implementation Details
|
88
|
-
== Evaluation Protocol
|
89
|
-
"""
|
90
|
-
lines: List[str] = []
|
91
|
-
for i, chapter in enumerate(self.chapters, 1):
|
92
|
-
lines.append(f"= Chapter {i}: {chapter.title}")
|
93
|
-
for j, section in enumerate(chapter.sections, 1):
|
94
|
-
lines.append(f"== {i}.{j} {section.title}")
|
95
|
-
for k, subsection in enumerate(section.subsections, 1):
|
96
|
-
lines.append(f"=== {i}.{j}.{k} {subsection.title}")
|
97
|
-
return "\n".join(lines)
|
98
|
-
|
99
|
-
@override
|
100
|
-
def iter_dfs(
|
101
|
-
self,
|
102
|
-
) -> Generator[ArticleChapterOutline | ArticleSectionOutline | ArticleSubsectionOutline, None, None]:
|
103
|
-
return super().iter_dfs()
|
104
|
-
def find_illegal(self) -> Optional[Tuple[ArticleOutlineBase, str]]:
|
105
|
-
"""Finds the first illegal component in the outline.
|
106
|
-
|
107
|
-
Returns:
|
108
|
-
Tuple[ArticleOutlineBase, str]: A tuple containing the illegal component and an error message.
|
109
|
-
"""
|
110
|
-
summary = ""
|
111
|
-
for component in self.iter_dfs():
|
112
|
-
for ref in component.depend_on:
|
113
|
-
if not ref.deref(self):
|
114
|
-
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"
|
115
|
-
for ref in component.support_to:
|
116
|
-
if not ref.deref(self):
|
117
|
-
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"
|
118
|
-
summary += component.introspect()
|
119
|
-
if summary:
|
120
|
-
return component, summary
|
121
|
-
return None
|
122
|
-
|
123
|
-
@classmethod
|
124
|
-
def from_typst_code(
|
125
|
-
cls, typst_code: str, title: str = "", article_language: str = "en", prospect: str = "", abstract: str = ""
|
126
|
-
) -> "ArticleOutline":
|
127
|
-
"""Parses a Typst code string and creates an ArticleOutline instance."""
|
128
|
-
self = cls(language=article_language, prospect=prospect, abstract=abstract, chapters=[], title=title)
|
129
|
-
stack = [self] # 根节点为ArticleOutline实例
|
130
|
-
|
131
|
-
for line in typst_code.splitlines():
|
132
|
-
parsed = cls._parse_line(line)
|
133
|
-
if not parsed:
|
134
|
-
continue
|
135
|
-
level, title = parsed
|
136
|
-
cls._adjust_stack(stack, level)
|
137
|
-
parent = stack[-1]
|
138
|
-
component = cls._create_component(level, title)
|
139
|
-
cls._add_to_parent(parent, component, level)
|
140
|
-
stack.append(component)
|
141
|
-
|
142
|
-
return self
|
143
|
-
|
144
|
-
@classmethod
|
145
|
-
def _parse_line(cls, line: str) -> Optional[Tuple[int, str]]:
|
146
|
-
stripped = line.strip()
|
147
|
-
if not stripped.startswith("="):
|
148
|
-
return None
|
149
|
-
match = regex.match(r"^(\=+)(.*)", stripped)
|
150
|
-
if not match:
|
151
|
-
return None
|
152
|
-
eqs, title_part = match.groups()
|
153
|
-
return len(eqs), title_part.strip()
|
154
|
-
|
155
|
-
@classmethod
|
156
|
-
def _adjust_stack(cls, stack: List[object], target_level: int) -> None:
|
157
|
-
while len(stack) > target_level:
|
158
|
-
stack.pop()
|
159
|
-
|
160
|
-
@classmethod
|
161
|
-
def _create_component(cls, level: int, title: str) -> ArticleOutlineBase:
|
162
|
-
default_kwargs = {
|
163
|
-
"writing_aim": [],
|
164
|
-
"depend_on": [],
|
165
|
-
"support_to": [],
|
166
|
-
"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(),
|
167
41
|
}
|
168
|
-
component_map = {
|
169
|
-
1: lambda: ArticleChapterOutline(title=title, sections=[], **default_kwargs),
|
170
|
-
2: lambda: ArticleSectionOutline(title=title, subsections=[], **default_kwargs),
|
171
|
-
3: lambda: ArticleSubsectionOutline(title=title, **default_kwargs),
|
172
|
-
}
|
173
|
-
return ok(component_map.get(level, lambda: None)(), "Invalid level")
|
174
|
-
|
175
|
-
@classmethod
|
176
|
-
def _add_to_parent(
|
177
|
-
cls,
|
178
|
-
parent: Union["ArticleOutline", ArticleChapterOutline, ArticleSectionOutline],
|
179
|
-
component: ArticleOutlineBase,
|
180
|
-
level: int,
|
181
|
-
) -> None:
|
182
|
-
if level == 1 and isinstance(component, ArticleChapterOutline):
|
183
|
-
parent.chapters.append(component)
|
184
|
-
elif level == 2 and isinstance(component, ArticleSectionOutline): # noqa: PLR2004
|
185
|
-
parent.sections.append(component)
|
186
|
-
elif level == 3 and isinstance(component, ArticleSubsectionOutline): # noqa: PLR2004
|
187
|
-
parent.subsections.append(component)
|