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,24 +1,23 @@
|
|
1
1
|
"""A foundation for hierarchical document components with dependency tracking."""
|
2
|
-
|
2
|
+
|
3
|
+
from abc import ABC, abstractmethod
|
3
4
|
from enum import StrEnum
|
4
|
-
from
|
5
|
+
from itertools import chain
|
6
|
+
from typing import Generator, List, Optional, Self, Tuple, overload
|
5
7
|
|
6
8
|
from fabricatio.models.generic import (
|
7
|
-
|
9
|
+
AsPrompt,
|
8
10
|
CensoredAble,
|
9
11
|
Display,
|
12
|
+
FinalizedDumpAble,
|
10
13
|
Introspect,
|
11
14
|
ModelHash,
|
12
15
|
PersistentAble,
|
13
|
-
|
16
|
+
ProposedUpdateAble,
|
14
17
|
ResolveUpdateConflict,
|
15
|
-
|
18
|
+
SequencePatch,
|
16
19
|
)
|
17
20
|
|
18
|
-
if TYPE_CHECKING:
|
19
|
-
from fabricatio.models.extra.article_main import Article
|
20
|
-
from fabricatio.models.extra.article_outline import ArticleOutline
|
21
|
-
|
22
21
|
|
23
22
|
class ReferringType(StrEnum):
|
24
23
|
"""Enumeration of different types of references that can be made in an article."""
|
@@ -28,7 +27,10 @@ class ReferringType(StrEnum):
|
|
28
27
|
SUBSECTION = "subsection"
|
29
28
|
|
30
29
|
|
31
|
-
|
30
|
+
type RefKey = Tuple[str, Optional[str], Optional[str]]
|
31
|
+
|
32
|
+
|
33
|
+
class ArticleRef(CensoredAble, ProposedUpdateAble):
|
32
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.
|
33
35
|
|
34
36
|
Examples:
|
@@ -61,30 +63,21 @@ class ArticleRef(CensoredAble):
|
|
61
63
|
```
|
62
64
|
"""
|
63
65
|
|
64
|
-
referred_subsection_title: Optional[str] = None
|
65
|
-
"""`title` Field of the referenced subsection."""
|
66
|
-
|
67
|
-
referred_section_title: Optional[str] = None
|
68
|
-
"""`title` Field of the referenced section."""
|
69
|
-
|
70
66
|
referred_chapter_title: str
|
71
67
|
"""`title` Field of the referenced chapter"""
|
68
|
+
referred_section_title: Optional[str] = None
|
69
|
+
"""`title` Field of the referenced section."""
|
70
|
+
referred_subsection_title: Optional[str] = None
|
71
|
+
"""`title` Field of the referenced subsection."""
|
72
72
|
|
73
|
-
def
|
74
|
-
"""
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
"""Dereference the reference to the actual section or subsection within the provided article."""
|
80
|
-
|
81
|
-
@overload
|
82
|
-
def deref(self, article: "ArticleOutline") -> Optional["ArticleOutlineBase"]:
|
83
|
-
"""Dereference the reference to the actual section or subsection within the provided article."""
|
73
|
+
def update_from_inner(self, other: Self) -> Self:
|
74
|
+
"""Updates the current instance with the attributes of another instance."""
|
75
|
+
self.referred_chapter_title = other.referred_chapter_title
|
76
|
+
self.referred_section_title = other.referred_section_title
|
77
|
+
self.referred_subsection_title = other.referred_subsection_title
|
78
|
+
return self
|
84
79
|
|
85
|
-
def deref(
|
86
|
-
self, article: Union["ArticleOutline", "Article"]
|
87
|
-
) -> Union["ArticleOutlineBase", "ArticleMainBase", None]:
|
80
|
+
def deref(self, article: "ArticleBase") -> Optional["ArticleOutlineBase"]:
|
88
81
|
"""Dereference the reference to the actual section or subsection within the provided article.
|
89
82
|
|
90
83
|
Args:
|
@@ -111,21 +104,74 @@ class ArticleRef(CensoredAble):
|
|
111
104
|
return ReferringType.CHAPTER
|
112
105
|
|
113
106
|
|
114
|
-
class
|
115
|
-
|
107
|
+
class ArticleMetaData(CensoredAble, Display):
|
108
|
+
"""Metadata for an article component."""
|
109
|
+
|
110
|
+
description: str
|
111
|
+
"""Description of the research component in academic style."""
|
112
|
+
|
113
|
+
support_to: List[ArticleRef]
|
114
|
+
"""List of references to other component of this articles that this component supports."""
|
115
|
+
depend_on: List[ArticleRef]
|
116
|
+
"""List of references to other component of this articles that this component depends on."""
|
117
|
+
|
118
|
+
writing_aim: List[str]
|
119
|
+
"""List of writing aims of the research component in academic style."""
|
120
|
+
title: str
|
121
|
+
"""Do not add any prefix or suffix to the title. should not contain special characters."""
|
122
|
+
|
123
|
+
|
124
|
+
class ArticleRefSequencePatch(SequencePatch[ArticleRef]):
|
125
|
+
"""Patch for article refs."""
|
126
|
+
|
127
|
+
|
128
|
+
class ArticleOutlineBase(
|
129
|
+
ArticleMetaData,
|
130
|
+
ResolveUpdateConflict,
|
131
|
+
ProposedUpdateAble,
|
132
|
+
PersistentAble,
|
133
|
+
ModelHash,
|
116
134
|
Introspect,
|
117
135
|
):
|
118
|
-
"""Base class for article
|
136
|
+
"""Base class for article outlines."""
|
119
137
|
|
120
|
-
|
121
|
-
|
138
|
+
@property
|
139
|
+
def metadata(self) -> ArticleMetaData:
|
140
|
+
"""Returns the metadata of the article component."""
|
141
|
+
return ArticleMetaData.model_validate(self, from_attributes=True)
|
142
|
+
|
143
|
+
def update_metadata(self, other: ArticleMetaData) -> Self:
|
144
|
+
"""Updates the metadata of the current instance with the attributes of another instance."""
|
145
|
+
self.support_to.clear()
|
146
|
+
self.support_to.extend(other.support_to)
|
147
|
+
self.depend_on.clear()
|
148
|
+
self.depend_on.extend(other.depend_on)
|
149
|
+
self.writing_aim.clear()
|
150
|
+
self.writing_aim.extend(other.writing_aim)
|
151
|
+
self.description = other.description
|
152
|
+
return self
|
122
153
|
|
154
|
+
def display_metadata(self) -> str:
|
155
|
+
"""Displays the metadata of the current instance."""
|
156
|
+
return self.model_dump_json(
|
157
|
+
indent=1, include={"title", "writing_aim", "description", "support_to", "depend_on"}
|
158
|
+
)
|
159
|
+
|
160
|
+
def update_from_inner(self, other: Self) -> Self:
|
161
|
+
"""Updates the current instance with the attributes of another instance."""
|
162
|
+
return self.update_metadata(other)
|
163
|
+
|
164
|
+
@abstractmethod
|
123
165
|
def to_typst_code(self) -> str:
|
124
166
|
"""Converts the component into a Typst code snippet for rendering."""
|
125
|
-
return f"=== {self.title}\n"
|
126
167
|
|
127
|
-
|
128
|
-
|
168
|
+
|
169
|
+
class SubSectionBase(ArticleOutlineBase):
|
170
|
+
"""Base class for article sections and subsections."""
|
171
|
+
|
172
|
+
def to_typst_code(self) -> str:
|
173
|
+
"""Converts the component into a Typst code snippet for rendering."""
|
174
|
+
return f"=== {self.title}\n"
|
129
175
|
|
130
176
|
def introspect(self) -> str:
|
131
177
|
"""Introspects the article subsection outline."""
|
@@ -138,16 +184,11 @@ class SubSectionBase(
|
|
138
184
|
return ""
|
139
185
|
|
140
186
|
|
141
|
-
class SectionBase[T: SubSectionBase](
|
142
|
-
UpdateFrom,
|
143
|
-
Introspect,
|
144
|
-
):
|
187
|
+
class SectionBase[T: SubSectionBase](ArticleOutlineBase):
|
145
188
|
"""Base class for article sections and subsections."""
|
146
189
|
|
147
190
|
subsections: List[T]
|
148
191
|
"""Subsections of the section. Contains at least one subsection. You can also add more as needed."""
|
149
|
-
title: str
|
150
|
-
"""Title of the section, do not add any prefix or suffix to the title. should not contain special characters."""
|
151
192
|
|
152
193
|
def to_typst_code(self) -> str:
|
153
194
|
"""Converts the section into a Typst formatted code snippet.
|
@@ -174,6 +215,7 @@ class SectionBase[T: SubSectionBase](
|
|
174
215
|
|
175
216
|
def update_from_inner(self, other: Self) -> Self:
|
176
217
|
"""Updates the current instance with the attributes of another instance."""
|
218
|
+
super().update_from_inner(other)
|
177
219
|
if len(self.subsections) == 0:
|
178
220
|
self.subsections = other.subsections
|
179
221
|
return self
|
@@ -189,16 +231,12 @@ class SectionBase[T: SubSectionBase](
|
|
189
231
|
return ""
|
190
232
|
|
191
233
|
|
192
|
-
class ChapterBase[T: SectionBase](
|
193
|
-
UpdateFrom,
|
194
|
-
Introspect,
|
195
|
-
):
|
234
|
+
class ChapterBase[T: SectionBase](ArticleOutlineBase):
|
196
235
|
"""Base class for article chapters."""
|
197
236
|
|
198
237
|
sections: List[T]
|
199
238
|
"""Sections of the chapter. Contains at least one section. You can also add more as needed."""
|
200
|
-
|
201
|
-
"""Title of the chapter, do not add any prefix or suffix to the title. should not contain special characters."""
|
239
|
+
|
202
240
|
def to_typst_code(self) -> str:
|
203
241
|
"""Converts the chapter into a Typst formatted code snippet for rendering."""
|
204
242
|
return f"= {self.title}\n" + "\n\n".join(sec.to_typst_code() for sec in self.sections)
|
@@ -233,21 +271,35 @@ class ChapterBase[T: SectionBase](
|
|
233
271
|
return ""
|
234
272
|
|
235
273
|
|
236
|
-
class ArticleBase[T: ChapterBase](
|
274
|
+
class ArticleBase[T: ChapterBase](FinalizedDumpAble, AsPrompt, ABC):
|
237
275
|
"""Base class for article outlines."""
|
238
276
|
|
277
|
+
language: str
|
278
|
+
"""Written language of the article. SHALL be aligned to the language of the article proposal provided."""
|
279
|
+
|
280
|
+
title: str
|
281
|
+
"""Title of the academic paper."""
|
282
|
+
|
283
|
+
prospect: str
|
284
|
+
"""Consolidated research statement with four pillars:
|
285
|
+
1. Problem Identification: Current limitations
|
286
|
+
2. Methodological Response: Technical approach
|
287
|
+
3. Empirical Validation: Evaluation strategy
|
288
|
+
4. Scholarly Impact: Field contributions
|
289
|
+
"""
|
290
|
+
|
291
|
+
abstract: str
|
292
|
+
"""The abstract is a concise summary of the academic paper's main findings."""
|
239
293
|
chapters: List[T]
|
240
294
|
"""Chapters of the article. Contains at least one chapter. You can also add more as needed."""
|
241
|
-
title: str
|
242
|
-
"""Title of the article outline, do not add any prefix or suffix to the title. should not contain special characters."""
|
243
295
|
|
244
|
-
def
|
296
|
+
def iter_dfs_rev(
|
245
297
|
self,
|
246
|
-
) -> Generator[
|
247
|
-
"""Performs a depth-first search (DFS) through the article structure.
|
298
|
+
) -> Generator[ArticleOutlineBase, None, None]:
|
299
|
+
"""Performs a depth-first search (DFS) through the article structure in reverse order.
|
248
300
|
|
249
301
|
Returns:
|
250
|
-
Generator[ArticleMainBase]: Each component in the article structure.
|
302
|
+
Generator[ArticleMainBase]: Each component in the article structure in reverse order.
|
251
303
|
"""
|
252
304
|
for chap in self.chapters:
|
253
305
|
for sec in chap.sections:
|
@@ -255,37 +307,121 @@ class ArticleBase[T: ChapterBase](Base):
|
|
255
307
|
yield sec
|
256
308
|
yield chap
|
257
309
|
|
310
|
+
def iter_dfs(self) -> Generator[ArticleOutlineBase, None, None]:
|
311
|
+
"""Performs a depth-first search (DFS) through the article structure.
|
258
312
|
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
ABC,
|
268
|
-
):
|
269
|
-
"""Base class for article outlines."""
|
313
|
+
Returns:
|
314
|
+
Generator[ArticleMainBase]: Each component in the article structure.
|
315
|
+
"""
|
316
|
+
for chap in self.chapters:
|
317
|
+
yield chap
|
318
|
+
for sec in chap.sections:
|
319
|
+
yield sec
|
320
|
+
yield from sec.subsections
|
270
321
|
|
271
|
-
|
272
|
-
|
322
|
+
def iter_support_on(self, rev: bool = False) -> Generator[ArticleRef, None, None]:
|
323
|
+
"""Iterates over all references that the article components support.
|
273
324
|
|
274
|
-
|
275
|
-
|
276
|
-
depend_on: List[ArticleRef]
|
277
|
-
"""List of references to other component of this articles that this component depends on."""
|
325
|
+
Args:
|
326
|
+
rev (bool): If True, iterate in reverse order.
|
278
327
|
|
279
|
-
|
280
|
-
|
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()])
|
281
335
|
|
282
|
-
def
|
283
|
-
"""
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
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
|
+
|
350
|
+
def iter_sections(self) -> Generator[Tuple[ChapterBase, SectionBase], None, None]:
|
351
|
+
"""Iterates through all sections in the article.
|
352
|
+
|
353
|
+
Returns:
|
354
|
+
Generator[ArticleOutlineBase]: Each section in the article.
|
355
|
+
"""
|
356
|
+
for chap in self.chapters:
|
357
|
+
for sec in chap.sections:
|
358
|
+
yield chap, sec
|
359
|
+
|
360
|
+
def iter_subsections(self) -> Generator[Tuple[ChapterBase, SectionBase, SubSectionBase], None, None]:
|
361
|
+
"""Iterates through all subsections in the article.
|
362
|
+
|
363
|
+
Returns:
|
364
|
+
Generator[ArticleOutlineBase]: Each subsection in the article.
|
365
|
+
"""
|
366
|
+
for chap, sec in self.iter_sections():
|
367
|
+
for subsec in sec.subsections:
|
368
|
+
yield chap, sec, subsec
|
369
|
+
|
370
|
+
def find_introspected(self) -> Optional[Tuple[ArticleOutlineBase, str]]:
|
371
|
+
"""Finds the first introspected component in the article structure."""
|
372
|
+
summary = ""
|
373
|
+
for component in self.iter_dfs_rev():
|
374
|
+
summary += component.introspect()
|
375
|
+
if summary:
|
376
|
+
return component, summary
|
377
|
+
return None
|
378
|
+
|
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]]:
|
386
|
+
"""Finds the first illegal component in the outline.
|
387
|
+
|
388
|
+
Returns:
|
389
|
+
Tuple[ArticleOutlineBase, str]: A tuple containing the illegal component and an error message.
|
390
|
+
"""
|
391
|
+
summary = ""
|
392
|
+
for component in self.iter_dfs_rev():
|
393
|
+
for ref in chain(component.depend_on, component.support_to):
|
394
|
+
if not ref.deref(self):
|
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"
|
396
|
+
if summary and not gather_identical:
|
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
|
+
|
405
|
+
return None
|
406
|
+
|
407
|
+
def finalized_dump(self) -> str:
|
408
|
+
"""Generates standardized hierarchical markup for academic publishing systems.
|
409
|
+
|
410
|
+
Implements ACL 2024 outline conventions with four-level structure:
|
411
|
+
= Chapter Title (Level 1)
|
412
|
+
== Section Title (Level 2)
|
413
|
+
=== Subsection Title (Level 3)
|
414
|
+
==== Subsubsection Title (Level 4)
|
415
|
+
|
416
|
+
Returns:
|
417
|
+
str: Strictly formatted outline with academic sectioning
|
418
|
+
|
419
|
+
Example:
|
420
|
+
= Methodology
|
421
|
+
== Neural Architecture Search Framework
|
422
|
+
=== Differentiable Search Space
|
423
|
+
==== Constrained Optimization Parameters
|
424
|
+
=== Implementation Details
|
425
|
+
== Evaluation Protocol
|
426
|
+
"""
|
427
|
+
return "\n\n".join(a.to_typst_code() for a in self.chapters)
|