fabricatio 0.2.8.dev0__cp312-cp312-manylinux_2_34_x86_64.whl → 0.2.8.dev2__cp312-cp312-manylinux_2_34_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fabricatio/_rust.cpython-312-x86_64-linux-gnu.so +0 -0
- fabricatio/_rust.pyi +50 -0
- fabricatio/actions/article.py +138 -19
- fabricatio/actions/article_rag.py +74 -19
- fabricatio/actions/output.py +36 -4
- fabricatio/capabilities/advanced_judge.py +23 -0
- fabricatio/capabilities/rating.py +1 -1
- fabricatio/capabilities/review.py +2 -2
- fabricatio/fs/curd.py +4 -0
- fabricatio/models/action.py +6 -5
- fabricatio/models/extra/advanced_judge.py +29 -0
- fabricatio/models/extra/article_base.py +27 -2
- fabricatio/models/extra/article_essence.py +60 -18
- fabricatio/models/extra/article_main.py +14 -1
- fabricatio/models/extra/article_outline.py +9 -0
- fabricatio/models/extra/article_proposal.py +19 -1
- fabricatio/models/generic.py +24 -11
- fabricatio-0.2.8.dev2.data/scripts/tdown +0 -0
- {fabricatio-0.2.8.dev0.dist-info → fabricatio-0.2.8.dev2.dist-info}/METADATA +1 -1
- {fabricatio-0.2.8.dev0.dist-info → fabricatio-0.2.8.dev2.dist-info}/RECORD +22 -20
- fabricatio-0.2.8.dev0.data/scripts/tdown +0 -0
- {fabricatio-0.2.8.dev0.dist-info → fabricatio-0.2.8.dev2.dist-info}/WHEEL +0 -0
- {fabricatio-0.2.8.dev0.dist-info → fabricatio-0.2.8.dev2.dist-info}/licenses/LICENSE +0 -0
Binary file
|
fabricatio/_rust.pyi
CHANGED
@@ -122,3 +122,53 @@ class BibManager:
|
|
122
122
|
Returns:
|
123
123
|
List of all titles in the bibliography
|
124
124
|
"""
|
125
|
+
|
126
|
+
def get_author_by_key(self, key: str) -> Optional[List[str]]:
|
127
|
+
"""Retrieve authors by citation key.
|
128
|
+
|
129
|
+
Args:
|
130
|
+
key: Citation key
|
131
|
+
|
132
|
+
Returns:
|
133
|
+
List of authors if found, None otherwise
|
134
|
+
"""
|
135
|
+
|
136
|
+
def get_year_by_key(self, key: str) -> Optional[int]:
|
137
|
+
"""Retrieve the publication year by citation key.
|
138
|
+
|
139
|
+
Args:
|
140
|
+
key: Citation key
|
141
|
+
|
142
|
+
Returns:
|
143
|
+
Publication year if found, None otherwise
|
144
|
+
"""
|
145
|
+
|
146
|
+
def get_abstract_by_key(self, key: str) -> Optional[str]:
|
147
|
+
"""Retrieve the abstract by citation key.
|
148
|
+
|
149
|
+
Args:
|
150
|
+
key: Citation key
|
151
|
+
|
152
|
+
Returns:
|
153
|
+
Abstract if found, None otherwise
|
154
|
+
"""
|
155
|
+
def get_title_by_key(self, key: str) -> Optional[str]:
|
156
|
+
"""Retrieve the title by citation key.
|
157
|
+
|
158
|
+
Args:
|
159
|
+
key: Citation key
|
160
|
+
|
161
|
+
Returns:
|
162
|
+
Title if found, None otherwise
|
163
|
+
"""
|
164
|
+
|
165
|
+
def get_field_by_key(self, key: str, field: str)-> Optional[str]:
|
166
|
+
"""Retrieve a specific field by citation key.
|
167
|
+
|
168
|
+
Args:
|
169
|
+
key: Citation key
|
170
|
+
field: Field name
|
171
|
+
|
172
|
+
Returns:
|
173
|
+
Field value if found, None otherwise
|
174
|
+
"""
|
fabricatio/actions/article.py
CHANGED
@@ -4,9 +4,12 @@ from asyncio import gather
|
|
4
4
|
from pathlib import Path
|
5
5
|
from typing import Any, Callable, List, Optional
|
6
6
|
|
7
|
+
from fabricatio._rust import BibManager
|
8
|
+
from fabricatio.capabilities.advanced_judge import AdvancedJudge
|
7
9
|
from fabricatio.fs import safe_text_read
|
8
10
|
from fabricatio.journal import logger
|
9
11
|
from fabricatio.models.action import Action
|
12
|
+
from fabricatio.models.extra.article_base import ArticleRefPatch
|
10
13
|
from fabricatio.models.extra.article_essence import ArticleEssence
|
11
14
|
from fabricatio.models.extra.article_main import Article
|
12
15
|
from fabricatio.models.extra.article_outline import ArticleOutline
|
@@ -38,11 +41,27 @@ class ExtractArticleEssence(Action):
|
|
38
41
|
|
39
42
|
# trim the references
|
40
43
|
contents = ["References".join(c.split("References")[:-1]) for c in map(reader, task_input.dependencies)]
|
41
|
-
return await self.propose(
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
44
|
+
return await self.propose(ArticleEssence, contents, **self.prepend_sys_msg())
|
45
|
+
|
46
|
+
|
47
|
+
class FixArticleEssence(Action):
|
48
|
+
"""Fix the article essence based on the bibtex key."""
|
49
|
+
|
50
|
+
async def _execute(
|
51
|
+
self,
|
52
|
+
bib_mgr: BibManager,
|
53
|
+
article_essence: List[ArticleEssence],
|
54
|
+
**_,
|
55
|
+
) -> None:
|
56
|
+
for a in article_essence:
|
57
|
+
if key := (bib_mgr.get_cite_key(a.title) or bib_mgr.get_cite_key_fuzzy(a.title)):
|
58
|
+
a.title = bib_mgr.get_title_by_key(key) or a.title
|
59
|
+
a.authors = bib_mgr.get_author_by_key(key) or a.authors
|
60
|
+
a.publication_year = bib_mgr.get_year_by_key(key) or a.publication_year
|
61
|
+
a.bibtex_cite_key = key
|
62
|
+
logger.info(f'Updated {a.title} with {key}')
|
63
|
+
else:
|
64
|
+
logger.warning(f"No key found for {a.title}")
|
46
65
|
|
47
66
|
|
48
67
|
class GenerateArticleProposal(Action):
|
@@ -88,10 +107,10 @@ class GenerateArticleProposal(Action):
|
|
88
107
|
return proposal
|
89
108
|
|
90
109
|
|
91
|
-
class
|
92
|
-
"""Generate the article based on the
|
110
|
+
class GenerateInitialOutline(Action):
|
111
|
+
"""Generate the initial article outline based on the article proposal."""
|
93
112
|
|
94
|
-
output_key: str = "
|
113
|
+
output_key: str = "initial_article_outline"
|
95
114
|
"""The key of the output data."""
|
96
115
|
|
97
116
|
async def _execute(
|
@@ -99,15 +118,28 @@ class GenerateOutline(Action):
|
|
99
118
|
article_proposal: ArticleProposal,
|
100
119
|
**_,
|
101
120
|
) -> Optional[ArticleOutline]:
|
102
|
-
|
121
|
+
return ok(
|
103
122
|
await self.propose(
|
104
123
|
ArticleOutline,
|
105
124
|
article_proposal.as_prompt(),
|
106
125
|
**self.prepend_sys_msg(),
|
107
126
|
),
|
108
|
-
"Could not generate the outline.",
|
109
|
-
)
|
127
|
+
"Could not generate the initial outline.",
|
128
|
+
).update_ref(article_proposal)
|
129
|
+
|
130
|
+
|
131
|
+
class FixIntrospectedErrors(Action):
|
132
|
+
"""Fix introspected errors in the article outline."""
|
133
|
+
|
134
|
+
output_key: str = "introspected_errors_fixed_outline"
|
135
|
+
"""The key of the output data."""
|
110
136
|
|
137
|
+
async def _execute(
|
138
|
+
self,
|
139
|
+
article_outline: ArticleOutline,
|
140
|
+
supervisor_check: bool = False,
|
141
|
+
**_,
|
142
|
+
) -> Optional[ArticleOutline]:
|
111
143
|
introspect_manual = ok(
|
112
144
|
await self.draft_rating_manual(
|
113
145
|
topic=(
|
@@ -118,21 +150,36 @@ class GenerateOutline(Action):
|
|
118
150
|
"Could not generate the rating manual.",
|
119
151
|
)
|
120
152
|
|
121
|
-
while pack :=
|
153
|
+
while pack := article_outline.find_introspected():
|
122
154
|
component, err = ok(pack)
|
123
155
|
logger.warning(f"Found introspected error: {err}")
|
124
156
|
corrected = ok(
|
125
157
|
await self.correct_obj(
|
126
158
|
component,
|
127
|
-
reference=f"# Original Article Outline\n{
|
159
|
+
reference=f"# Original Article Outline\n{article_outline.display()}\n# Error Need to be fixed\n{err}",
|
128
160
|
topic=intro_topic,
|
129
161
|
rating_manual=introspect_manual,
|
130
|
-
supervisor_check=
|
162
|
+
supervisor_check=supervisor_check,
|
131
163
|
),
|
132
164
|
"Could not correct the component.",
|
133
165
|
)
|
134
166
|
component.update_from(corrected)
|
135
167
|
|
168
|
+
return article_outline
|
169
|
+
|
170
|
+
|
171
|
+
class FixIllegalReferences(Action):
|
172
|
+
"""Fix illegal references in the article outline."""
|
173
|
+
|
174
|
+
output_key: str = "illegal_references_fixed_outline"
|
175
|
+
"""The key of the output data."""
|
176
|
+
|
177
|
+
async def _execute(
|
178
|
+
self,
|
179
|
+
article_outline: ArticleOutline,
|
180
|
+
supervisor_check: bool = False,
|
181
|
+
**_,
|
182
|
+
) -> Optional[ArticleOutline]:
|
136
183
|
ref_manual = ok(
|
137
184
|
await self.draft_rating_manual(
|
138
185
|
topic=(
|
@@ -143,19 +190,89 @@ class GenerateOutline(Action):
|
|
143
190
|
"Could not generate the rating manual.",
|
144
191
|
)
|
145
192
|
|
146
|
-
while pack :=
|
193
|
+
while pack := article_outline.find_illegal_ref():
|
147
194
|
ref, err = ok(pack)
|
148
195
|
logger.warning(f"Found illegal referring error: {err}")
|
149
196
|
ok(
|
150
197
|
await self.correct_obj_inplace(
|
151
198
|
ref,
|
152
|
-
reference=f"# Original Article Outline\n{
|
199
|
+
reference=f"# Original Article Outline\n{article_outline.display()}\n# Error Need to be fixed\n{err}",
|
153
200
|
topic=ref_topic,
|
154
201
|
rating_manual=ref_manual,
|
155
|
-
supervisor_check=
|
202
|
+
supervisor_check=supervisor_check,
|
156
203
|
)
|
157
204
|
)
|
158
|
-
return
|
205
|
+
return article_outline.update_ref(article_outline)
|
206
|
+
|
207
|
+
|
208
|
+
class TweakOutlineBackwardRef(Action, AdvancedJudge):
|
209
|
+
"""Tweak the backward references in the article outline.
|
210
|
+
|
211
|
+
Ensures that the prerequisites of the current chapter are correctly referenced in the `depend_on` field.
|
212
|
+
"""
|
213
|
+
|
214
|
+
output_key: str = "article_outline_bw_ref_checked"
|
215
|
+
|
216
|
+
async def _execute(self, article_outline: ArticleOutline, supervisor_check: bool = False, **cxt) -> ArticleOutline:
|
217
|
+
tweak_depend_on_manual = ok(
|
218
|
+
await self.draft_rating_manual(
|
219
|
+
topic := "Ensure prerequisites are correctly referenced in the `depend_on` field."
|
220
|
+
),
|
221
|
+
"Could not generate the rating manual.",
|
222
|
+
)
|
223
|
+
|
224
|
+
for a in article_outline.iter_dfs():
|
225
|
+
if await self.evidently_judge(
|
226
|
+
f"{article_outline.as_prompt()}\n\n{a.display()}\n"
|
227
|
+
f"Does the `{a.__class__.__name__}`'s `depend_on` field need to be extended or tweaked?"
|
228
|
+
):
|
229
|
+
patch = ArticleRefPatch.default()
|
230
|
+
patch.tweaked = a.depend_on
|
231
|
+
|
232
|
+
await self.correct_obj_inplace(
|
233
|
+
patch,
|
234
|
+
topic=topic,
|
235
|
+
reference=f"{article_outline.as_prompt()}\nThe Article component whose `depend_on` field needs to be extended or tweaked",
|
236
|
+
rating_manual=tweak_depend_on_manual,
|
237
|
+
supervisor_check=supervisor_check,
|
238
|
+
)
|
239
|
+
|
240
|
+
return article_outline
|
241
|
+
|
242
|
+
|
243
|
+
class TweakOutlineForwardRef(Action, AdvancedJudge):
|
244
|
+
"""Tweak the forward references in the article outline.
|
245
|
+
|
246
|
+
Ensures that the conclusions of the current chapter effectively support the analysis of subsequent chapters.
|
247
|
+
"""
|
248
|
+
|
249
|
+
output_key: str = "article_outline_fw_ref_checked"
|
250
|
+
|
251
|
+
async def _execute(self, article_outline: ArticleOutline, supervisor_check: bool = False, **cxt) -> ArticleOutline:
|
252
|
+
tweak_support_to_manual = ok(
|
253
|
+
await self.draft_rating_manual(
|
254
|
+
topic := "Ensure conclusions support the analysis of subsequent chapters, sections or subsections."
|
255
|
+
),
|
256
|
+
"Could not generate the rating manual.",
|
257
|
+
)
|
258
|
+
|
259
|
+
for a in article_outline.iter_dfs():
|
260
|
+
if await self.evidently_judge(
|
261
|
+
f"{article_outline.as_prompt()}\n\n{a.display()}\n"
|
262
|
+
f"Does the `{a.__class__.__name__}`'s `support_to` field need to be extended or tweaked?"
|
263
|
+
):
|
264
|
+
patch = ArticleRefPatch.default()
|
265
|
+
patch.tweaked = a.support_to
|
266
|
+
|
267
|
+
await self.correct_obj_inplace(
|
268
|
+
patch,
|
269
|
+
topic=topic,
|
270
|
+
reference=f"{article_outline.as_prompt()}\nThe Article component whose `support_to` field needs to be extended or tweaked",
|
271
|
+
rating_manual=tweak_support_to_manual,
|
272
|
+
supervisor_check=supervisor_check,
|
273
|
+
)
|
274
|
+
|
275
|
+
return article_outline
|
159
276
|
|
160
277
|
|
161
278
|
class GenerateArticle(Action):
|
@@ -167,6 +284,7 @@ class GenerateArticle(Action):
|
|
167
284
|
async def _execute(
|
168
285
|
self,
|
169
286
|
article_outline: ArticleOutline,
|
287
|
+
supervisor_check: bool = False,
|
170
288
|
**_,
|
171
289
|
) -> Optional[Article]:
|
172
290
|
article: Article = Article.from_outline(ok(article_outline, "Article outline not specified.")).update_ref(
|
@@ -184,13 +302,14 @@ class GenerateArticle(Action):
|
|
184
302
|
reference=f"# Original Article Outline\n{article_outline.display()}\n# Error Need to be fixed\n{err}",
|
185
303
|
topic=w_topic,
|
186
304
|
rating_manual=write_para_manual,
|
187
|
-
supervisor_check=
|
305
|
+
supervisor_check=supervisor_check,
|
188
306
|
)
|
189
307
|
for _, __, subsec in article.iter_subsections()
|
190
308
|
if (err := subsec.introspect())
|
191
309
|
],
|
192
310
|
return_exceptions=True,
|
193
311
|
)
|
312
|
+
|
194
313
|
return article
|
195
314
|
|
196
315
|
|
@@ -1,35 +1,90 @@
|
|
1
1
|
"""A module for writing articles using RAG (Retrieval-Augmented Generation) capabilities."""
|
2
2
|
|
3
|
-
from
|
3
|
+
from asyncio import gather
|
4
|
+
from typing import Dict, Optional
|
4
5
|
|
5
6
|
from fabricatio.capabilities.rag import RAG
|
6
|
-
from fabricatio.journal import logger
|
7
7
|
from fabricatio.models.action import Action
|
8
|
-
from fabricatio.models.extra.article_main import Article
|
9
|
-
from fabricatio.models.
|
8
|
+
from fabricatio.models.extra.article_main import Article, ArticleParagraphPatch, ArticleSubsection
|
9
|
+
from fabricatio.models.utils import ok
|
10
10
|
|
11
11
|
|
12
|
-
class
|
12
|
+
class TweakArticleRAG(Action, RAG):
|
13
13
|
"""Write an article based on the provided outline."""
|
14
14
|
|
15
|
-
output_key: str = "
|
15
|
+
output_key: str = "rag_tweaked_article"
|
16
16
|
|
17
|
-
async def _execute(
|
17
|
+
async def _execute(
|
18
|
+
self,
|
19
|
+
article: Article,
|
20
|
+
collection_name: str = "article_essence",
|
21
|
+
citation_requirement: str = "# Citation Format\n"
|
22
|
+
"Use correct citation format based on author count. Cite using author surnames and year:"
|
23
|
+
"For 3+ authors: 'Author1, Author2 et al. (YYYY)'"
|
24
|
+
"For 2 authors: 'Author1 & Author2 (YYYY)'"
|
25
|
+
"Single author: 'Author1 (YYYY)'"
|
26
|
+
"Multiple citations: 'Author1 (YYYY), Author2 (YYYY)'"
|
27
|
+
"Prioritize formulas from reference highlights."
|
28
|
+
"Specify authors/years only - no numeric citations"
|
29
|
+
"Paragraphs must exceed 2-3 sentences",
|
30
|
+
supervisor_check: bool = False,
|
31
|
+
parallel: bool = False,
|
32
|
+
**cxt,
|
33
|
+
) -> Optional[Article]:
|
18
34
|
"""Write an article based on the provided outline."""
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
35
|
+
criteria = await self.draft_rating_criteria(
|
36
|
+
topic := "choose appropriate reference to insert into the article, "
|
37
|
+
"making conclusions or reasoning based on concrete evidence instead of unreliable guesses."
|
38
|
+
"Extensively use formulas highlighted in reference文献 should be translated to 'references'."
|
39
|
+
"Only specify authors and years without numeric citation numbers (like [1],[2])."
|
40
|
+
"Each paragraph should not end with just 2-3 sentences for better readability.",
|
41
|
+
criteria_count=13,
|
25
42
|
)
|
26
43
|
|
44
|
+
tweak_manual = ok(
|
45
|
+
await self.draft_rating_manual(topic, criteria=criteria, co_extractor={"model": "openai/qwen-max"})
|
46
|
+
)
|
47
|
+
self.view(collection_name)
|
27
48
|
|
28
|
-
|
29
|
-
|
49
|
+
if parallel:
|
50
|
+
await gather(
|
51
|
+
*[
|
52
|
+
self._inner(article, subsec, supervisor_check, citation_requirement, topic, tweak_manual)
|
53
|
+
for _, __, subsec in article.iter_subsections()
|
54
|
+
],
|
55
|
+
return_exceptions=True,
|
56
|
+
)
|
57
|
+
else:
|
58
|
+
for _, __, subsec in article.iter_subsections():
|
59
|
+
await self._inner(article, subsec, supervisor_check, citation_requirement, topic, tweak_manual)
|
30
60
|
|
31
|
-
|
61
|
+
return article
|
32
62
|
|
33
|
-
async def
|
34
|
-
|
35
|
-
|
63
|
+
async def _inner(
|
64
|
+
self,
|
65
|
+
article: Article,
|
66
|
+
subsec: ArticleSubsection,
|
67
|
+
supervisor_check: bool,
|
68
|
+
citation_requirement: str,
|
69
|
+
topic: str,
|
70
|
+
tweak_manual: Dict[str, str],
|
71
|
+
) -> None:
|
72
|
+
refind_q = ok(
|
73
|
+
await self.arefined_query(
|
74
|
+
f"{article.referenced.as_prompt()}\n"
|
75
|
+
f"# Subsection requiring reference enhancement\n"
|
76
|
+
f"{subsec.display()}\n"
|
77
|
+
f"# Requirement\n"
|
78
|
+
f"Search related articles in the base to find reference candidates, "
|
79
|
+
f"prioritizing both original article language and English usage",
|
80
|
+
)
|
81
|
+
)
|
82
|
+
patch = ArticleParagraphPatch.default()
|
83
|
+
patch.tweaked = subsec.paragraphs
|
84
|
+
await self.correct_obj_inplace(
|
85
|
+
patch,
|
86
|
+
reference=f"{await self.aretrieve_compact(refind_q, final_limit=50)}\n{citation_requirement}",
|
87
|
+
topic=topic,
|
88
|
+
rating_manual=tweak_manual,
|
89
|
+
supervisor_check=supervisor_check,
|
90
|
+
)
|
fabricatio/actions/output.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
"""Dump the finalized output to a file."""
|
2
2
|
|
3
3
|
from pathlib import Path
|
4
|
-
from typing import Optional
|
4
|
+
from typing import Iterable, List, Optional, Type
|
5
5
|
|
6
6
|
from fabricatio.journal import logger
|
7
7
|
from fabricatio.models.action import Action
|
@@ -14,6 +14,7 @@ class DumpFinalizedOutput(Action):
|
|
14
14
|
"""Dump the finalized output to a file."""
|
15
15
|
|
16
16
|
output_key: str = "dump_path"
|
17
|
+
dump_path: Optional[str] = None
|
17
18
|
|
18
19
|
async def _execute(
|
19
20
|
self,
|
@@ -24,6 +25,7 @@ class DumpFinalizedOutput(Action):
|
|
24
25
|
) -> str:
|
25
26
|
dump_path = Path(
|
26
27
|
dump_path
|
28
|
+
or self.dump_path
|
27
29
|
or ok(
|
28
30
|
await self.awhich_pathstr(
|
29
31
|
f"{ok(task_input, 'Neither `task_input` and `dump_path` is provided.').briefing}\n\nExtract a single path of the file, to which I will dump the data."
|
@@ -39,6 +41,7 @@ class PersistentAll(Action):
|
|
39
41
|
"""Persist all the data to a file."""
|
40
42
|
|
41
43
|
output_key: str = "persistent_count"
|
44
|
+
persist_dir: Optional[str] = None
|
42
45
|
|
43
46
|
async def _execute(
|
44
47
|
self,
|
@@ -48,6 +51,7 @@ class PersistentAll(Action):
|
|
48
51
|
) -> int:
|
49
52
|
persist_dir = Path(
|
50
53
|
persist_dir
|
54
|
+
or self.persist_dir
|
51
55
|
or ok(
|
52
56
|
await self.awhich_pathstr(
|
53
57
|
f"{ok(task_input, 'Neither `task_input` and `dump_path` is provided.').briefing}\n\nExtract a single path of the file, to which I will persist the data."
|
@@ -60,10 +64,38 @@ class PersistentAll(Action):
|
|
60
64
|
if persist_dir.is_file():
|
61
65
|
logger.warning("Dump should be a directory, but it is a file. Skip dumping.")
|
62
66
|
return count
|
63
|
-
|
64
|
-
for v in cxt.
|
67
|
+
|
68
|
+
for k, v in cxt.items():
|
69
|
+
final_dir = persist_dir.joinpath(k)
|
70
|
+
final_dir.mkdir(parents=True, exist_ok=True)
|
65
71
|
if isinstance(v, PersistentAble):
|
66
|
-
v.persist(
|
72
|
+
v.persist(final_dir)
|
67
73
|
count += 1
|
74
|
+
if isinstance(v, Iterable) and any(
|
75
|
+
persistent_ables := (pers for pers in v if isinstance(pers, PersistentAble))
|
76
|
+
):
|
77
|
+
for per in persistent_ables:
|
78
|
+
per.persist(final_dir)
|
79
|
+
count += 1
|
68
80
|
|
69
81
|
return count
|
82
|
+
|
83
|
+
|
84
|
+
class RetrieveFromPersistent[T: PersistentAble](Action):
|
85
|
+
"""Retrieve the object from the persistent file."""
|
86
|
+
|
87
|
+
output_key: str = "retrieved_obj"
|
88
|
+
"""Retrieve the object from the persistent file."""
|
89
|
+
load_path: str
|
90
|
+
"""The path of the persistent file or directory contains multiple file."""
|
91
|
+
retrieve_cls: Type[T]
|
92
|
+
"""The class of the object to retrieve."""
|
93
|
+
|
94
|
+
async def _execute(self, /, **__) -> Optional[T | List[T]]:
|
95
|
+
logger.info(f"Retrieve `{self.retrieve_cls.__name__}` from persistent file: {self.load_path}")
|
96
|
+
if not (p := Path(self.load_path)).exists():
|
97
|
+
return None
|
98
|
+
|
99
|
+
if p.is_dir():
|
100
|
+
return [self.retrieve_cls.from_persistent(per) for per in p.glob("*")]
|
101
|
+
return self.retrieve_cls.from_persistent(self.load_path)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
"""The Capabilities module for advanced judging."""
|
2
|
+
|
3
|
+
from typing import Optional, Unpack
|
4
|
+
|
5
|
+
from fabricatio.capabilities.propose import Propose
|
6
|
+
from fabricatio.models.extra.advanced_judge import JudgeMent
|
7
|
+
from fabricatio.models.kwargs_types import ValidateKwargs
|
8
|
+
|
9
|
+
|
10
|
+
class AdvancedJudge(Propose):
|
11
|
+
"""A class that judges the evidence and makes a final decision."""
|
12
|
+
async def evidently_judge(
|
13
|
+
self,
|
14
|
+
prompt: str,
|
15
|
+
**kwargs: Unpack[ValidateKwargs[JudgeMent]],
|
16
|
+
) -> Optional[JudgeMent]:
|
17
|
+
"""Judge the evidence and make a final decision."""
|
18
|
+
return await self.propose(
|
19
|
+
JudgeMent,
|
20
|
+
prompt,
|
21
|
+
**kwargs
|
22
|
+
)
|
23
|
+
|
@@ -16,7 +16,7 @@ from more_itertools import flatten, windowed
|
|
16
16
|
from pydantic import NonNegativeInt, PositiveInt
|
17
17
|
|
18
18
|
|
19
|
-
class
|
19
|
+
class Rating(WithBriefing, LLMUsage):
|
20
20
|
"""A class that provides functionality to rate tasks based on a rating manual and score range.
|
21
21
|
|
22
22
|
References:
|
@@ -4,7 +4,7 @@ from typing import Dict, List, Optional, Self, Set, Unpack, cast
|
|
4
4
|
|
5
5
|
from fabricatio._rust_instances import TEMPLATE_MANAGER
|
6
6
|
from fabricatio.capabilities.propose import Propose
|
7
|
-
from fabricatio.capabilities.rating import
|
7
|
+
from fabricatio.capabilities.rating import Rating
|
8
8
|
from fabricatio.config import configs
|
9
9
|
from fabricatio.models.generic import Base, Display, ProposedAble, WithBriefing
|
10
10
|
from fabricatio.models.kwargs_types import ReviewKwargs, ValidateKwargs
|
@@ -175,7 +175,7 @@ class ReviewResult[T](ProposedAble, Display):
|
|
175
175
|
return self
|
176
176
|
|
177
177
|
|
178
|
-
class Review(
|
178
|
+
class Review(Rating, Propose):
|
179
179
|
"""Class that provides functionality to review tasks and strings using a language model.
|
180
180
|
|
181
181
|
This class extends GiveRating and Propose capabilities to analyze content,
|
fabricatio/fs/curd.py
CHANGED
@@ -145,5 +145,9 @@ def gather_files(directory: str | Path | PathLike, extension: str) -> list[str]:
|
|
145
145
|
|
146
146
|
Returns:
|
147
147
|
list[str]: A list of file paths with the specified extension.
|
148
|
+
|
149
|
+
Example:
|
150
|
+
>>> gather_files('/path/to/directory', 'txt')
|
151
|
+
['/path/to/directory/file1.txt', '/path/to/directory/file2.txt']
|
148
152
|
"""
|
149
153
|
return [file.as_posix() for file in Path(directory).rglob(f"*.{extension}")]
|
fabricatio/models/action.py
CHANGED
@@ -104,7 +104,7 @@ class WorkFlow(WithBriefing, ToolBoxUsage):
|
|
104
104
|
_instances: Tuple[Action, ...] = PrivateAttr(default_factory=tuple)
|
105
105
|
"""Instantiated action objects to be executed in this workflow."""
|
106
106
|
|
107
|
-
steps: Tuple[Union[Type[Action], Action], ...] = Field(
|
107
|
+
steps: Tuple[Union[Type[Action], Action], ...] = Field(frozen=True,)
|
108
108
|
"""The sequence of actions to be executed, can be action classes or instances."""
|
109
109
|
|
110
110
|
task_input_key: str = Field(default="task_input")
|
@@ -157,13 +157,14 @@ class WorkFlow(WithBriefing, ToolBoxUsage):
|
|
157
157
|
# Process each action in sequence
|
158
158
|
for step in self._instances:
|
159
159
|
current_action = step.name
|
160
|
-
logger.info(f"Executing step
|
160
|
+
logger.info(f"Executing step >> {current_action}")
|
161
161
|
|
162
162
|
# Get current context and execute action
|
163
163
|
context = await self._context.get()
|
164
164
|
act_task = create_task(step.act(context))
|
165
165
|
# Handle task cancellation
|
166
166
|
if task.is_cancelled():
|
167
|
+
logger.warning(f"Task cancelled by task: {task.name}")
|
167
168
|
act_task.cancel(f"Cancelled by task: {task.name}")
|
168
169
|
break
|
169
170
|
|
@@ -171,7 +172,7 @@ class WorkFlow(WithBriefing, ToolBoxUsage):
|
|
171
172
|
modified_ctx = await act_task
|
172
173
|
logger.success(f"Step execution finished: {current_action}")
|
173
174
|
if step.output_key:
|
174
|
-
logger.success(f"Setting output
|
175
|
+
logger.success(f"Setting output to `{step.output_key}`")
|
175
176
|
await self._context.put(modified_ctx)
|
176
177
|
|
177
178
|
logger.success(f"Workflow execution finished: {self.name}")
|
@@ -182,7 +183,7 @@ class WorkFlow(WithBriefing, ToolBoxUsage):
|
|
182
183
|
|
183
184
|
if self.task_output_key not in final_ctx:
|
184
185
|
logger.warning(
|
185
|
-
f"Task output key: {self.task_output_key} not found in the context, None will be returned. "
|
186
|
+
f"Task output key: `{self.task_output_key}` not found in the context, None will be returned. "
|
186
187
|
f"You can check if `Action.output_key` is set the same as `WorkFlow.task_output_key`."
|
187
188
|
)
|
188
189
|
|
@@ -221,7 +222,7 @@ class WorkFlow(WithBriefing, ToolBoxUsage):
|
|
221
222
|
self.provide_tools_to(self._instances)
|
222
223
|
return self
|
223
224
|
|
224
|
-
def update_init_context(self, **kwargs) -> Self:
|
225
|
+
def update_init_context(self, /, **kwargs) -> Self:
|
225
226
|
"""Update the initial context with additional key-value pairs.
|
226
227
|
|
227
228
|
Args:
|
@@ -0,0 +1,29 @@
|
|
1
|
+
"""Module containing the JudgeMent class for holding judgment results."""
|
2
|
+
|
3
|
+
from typing import List
|
4
|
+
|
5
|
+
from fabricatio.models.generic import ProposedAble
|
6
|
+
|
7
|
+
|
8
|
+
class JudgeMent(ProposedAble):
|
9
|
+
"""Represents a judgment result containing supporting/denying evidence and final verdict.
|
10
|
+
|
11
|
+
The class stores both affirmative and denies evidence lists along with the final boolean judgment.
|
12
|
+
"""
|
13
|
+
|
14
|
+
affirm_evidence: List[str]
|
15
|
+
"""List of evidence supporting the affirmation."""
|
16
|
+
|
17
|
+
deny_evidence: List[str]
|
18
|
+
"""List of evidence supporting the denial."""
|
19
|
+
|
20
|
+
final_judgement: bool
|
21
|
+
"""The final judgment made according to all extracted evidence."""
|
22
|
+
|
23
|
+
def __bool__(self) -> bool:
|
24
|
+
"""Return the final judgment value.
|
25
|
+
|
26
|
+
Returns:
|
27
|
+
bool: The stored final_judgement value indicating the judgment result.
|
28
|
+
"""
|
29
|
+
return self.final_judgement
|
@@ -1,12 +1,13 @@
|
|
1
1
|
"""A foundation for hierarchical document components with dependency tracking."""
|
2
2
|
|
3
|
-
from abc import abstractmethod
|
3
|
+
from abc import ABC, abstractmethod
|
4
4
|
from enum import StrEnum
|
5
5
|
from functools import cache
|
6
6
|
from itertools import chain
|
7
7
|
from typing import Generator, List, Optional, Self, Tuple
|
8
8
|
|
9
9
|
from fabricatio.models.generic import (
|
10
|
+
AsPrompt,
|
10
11
|
CensoredAble,
|
11
12
|
Display,
|
12
13
|
FinalizedDumpAble,
|
@@ -121,6 +122,30 @@ class ArticleMetaData(CensoredAble, Display):
|
|
121
122
|
"""Do not add any prefix or suffix to the title. should not contain special characters."""
|
122
123
|
|
123
124
|
|
125
|
+
class Patch[T](ProposedUpdateAble, Display):
|
126
|
+
"""Base class for patches."""
|
127
|
+
|
128
|
+
tweaked: List[T]
|
129
|
+
"""Tweaked content list"""
|
130
|
+
def update_from_inner(self, other: Self) -> Self:
|
131
|
+
"""Updates the current instance with the attributes of another instance."""
|
132
|
+
self.tweaked.clear()
|
133
|
+
self.tweaked.extend(other.tweaked)
|
134
|
+
return self
|
135
|
+
|
136
|
+
|
137
|
+
@classmethod
|
138
|
+
def default(cls) -> Self:
|
139
|
+
"""Defaults to empty list."""
|
140
|
+
return cls(tweaked=[])
|
141
|
+
|
142
|
+
|
143
|
+
class ArticleRefPatch(Patch[ArticleRef]):
|
144
|
+
"""Patch for article refs."""
|
145
|
+
|
146
|
+
|
147
|
+
|
148
|
+
|
124
149
|
class ArticleOutlineBase(
|
125
150
|
ArticleMetaData,
|
126
151
|
ResolveUpdateConflict,
|
@@ -267,7 +292,7 @@ class ChapterBase[T: SectionBase](ArticleOutlineBase):
|
|
267
292
|
return ""
|
268
293
|
|
269
294
|
|
270
|
-
class ArticleBase[T: ChapterBase](FinalizedDumpAble):
|
295
|
+
class ArticleBase[T: ChapterBase](FinalizedDumpAble, AsPrompt, ABC):
|
271
296
|
"""Base class for article outlines."""
|
272
297
|
|
273
298
|
language: str
|
@@ -1,8 +1,8 @@
|
|
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
|
5
|
+
from fabricatio.models.generic import Display, PersistentAble, PrepareVectorization, ProposedAble
|
6
6
|
from pydantic import BaseModel, Field
|
7
7
|
|
8
8
|
|
@@ -20,12 +20,49 @@ class Equation(BaseModel):
|
|
20
20
|
Example: "Defines constrained search space dimensionality reduction. Used in architecture optimization phase (Section 3.2). Enables 40% parameter reduction."
|
21
21
|
"""
|
22
22
|
|
23
|
-
|
24
|
-
"""
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
23
|
+
typst_code: str
|
24
|
+
r"""The typst code for the equation, including the equation itself and any necessary formatting.
|
25
|
+
#let x = 5 // Define a code variable
|
26
|
+
|
27
|
+
// Basic syntax examples
|
28
|
+
$x^2$ // Inline formula
|
29
|
+
$ x^2 $ // Block formula (spaces before/after $ for standalone display)
|
30
|
+
|
31
|
+
// Variables and text handling
|
32
|
+
$ A = pi r^2 $ // Single-letter variables as-is
|
33
|
+
$"area" = pi dot "radius"^2 $ // Multi-letter variables in quotes
|
34
|
+
$ cal(A) := { x in RR | x "is natural" } $ // Calligraphic font and text
|
35
|
+
$ #x < 17 $ // Access code variables with #
|
36
|
+
|
37
|
+
// Symbols and shorthands
|
38
|
+
$x < y => x gt.eq.not y $ // Symbol shorthand (=> for ⇒, gt.eq.not for ≯)
|
39
|
+
|
40
|
+
// Multi-line equations with alignment
|
41
|
+
$ sum_(k=0)^n k
|
42
|
+
&= 1 + ... + n \
|
43
|
+
&= (n(n+1))/2 $ // Multi-line with & alignment
|
44
|
+
|
45
|
+
// Function calls and formatting
|
46
|
+
$ frac(a^2, 2) $ // Fraction
|
47
|
+
$ vec(1, 2, delim: "[") $ // Custom vector delimiter
|
48
|
+
$ mat(1, 2; 3, 4) $ // 2D matrix (semicolon separates rows)
|
49
|
+
$ mat(..#range(1, 5).chunks(2)) $ // Dynamic matrix with array expansion
|
50
|
+
|
51
|
+
// Advanced alignment example
|
52
|
+
$ (3x + y)/7 &= 9 && "given" \
|
53
|
+
3x + y &= 63 & "multiply by 7" \
|
54
|
+
3x &= 63 - y && "subtract y" \
|
55
|
+
x &= 21 - y/3 & "divide by 3" $
|
56
|
+
// && skips a column alignment (left/right alternation)
|
57
|
+
|
58
|
+
// Math font configuration
|
59
|
+
#show math.equation: set text(font: "Fira Math") // Set math font (requires Fira Math installed)
|
60
|
+
$ sum_(i in NN) 1 + i $ // Display with new font
|
61
|
+
|
62
|
+
// Escaping and special syntax
|
63
|
+
$ frac(a\,, b) $ // Escape comma to display as literal
|
64
|
+
$ f(x; y) $ // Literal semicolon (not for 2D arrays)
|
65
|
+
$ lim_x = op("lim", limits: #true)_x $ // Custom operator with limits
|
29
66
|
"""
|
30
67
|
|
31
68
|
|
@@ -133,11 +170,11 @@ class Highlightings(BaseModel):
|
|
133
170
|
"""
|
134
171
|
|
135
172
|
|
136
|
-
class ArticleEssence(ProposedAble, Display, PrepareVectorization):
|
137
|
-
"""
|
173
|
+
class ArticleEssence(ProposedAble, Display, PersistentAble, PrepareVectorization):
|
174
|
+
"""ArticleEssence is a structured representation of the core elements of a scientific article,using its original language."""
|
138
175
|
|
139
|
-
|
140
|
-
"""
|
176
|
+
language: str
|
177
|
+
"""Language of the original article, note that you should not attempt to translate the original language when generating JSON."""
|
141
178
|
|
142
179
|
title: str = Field(...)
|
143
180
|
"""Exact title of the original article without any modification.
|
@@ -149,7 +186,7 @@ class ArticleEssence(ProposedAble, Display, PrepareVectorization):
|
|
149
186
|
"""
|
150
187
|
|
151
188
|
authors: List[str]
|
152
|
-
"""Original author names exactly as they appear in the source document. No translation or paraphrasing.
|
189
|
+
"""Original author full names exactly as they appear in the source document. No translation or paraphrasing.
|
153
190
|
Extract complete list without any modifications or formatting changes."""
|
154
191
|
|
155
192
|
keywords: List[str]
|
@@ -170,11 +207,7 @@ class ArticleEssence(ProposedAble, Display, PrepareVectorization):
|
|
170
207
|
"""Domain tags for research focus."""
|
171
208
|
|
172
209
|
abstract: str = Field(...)
|
173
|
-
"""
|
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"""
|
210
|
+
"""Abstract text with original language."""
|
178
211
|
|
179
212
|
core_contributions: List[str]
|
180
213
|
"""3-5 technical contributions using CRediT taxonomy verbs.
|
@@ -184,6 +217,7 @@ class ArticleEssence(ProposedAble, Display, PrepareVectorization):
|
|
184
217
|
- 'Established cross-lingual transfer metrics'"""
|
185
218
|
|
186
219
|
technical_novelty: List[str]
|
220
|
+
|
187
221
|
"""Patent-style claims with technical specificity.
|
188
222
|
Format: 'A [system/method] comprising [novel components]...'
|
189
223
|
Example:
|
@@ -222,5 +256,13 @@ class ArticleEssence(ProposedAble, Display, PrepareVectorization):
|
|
222
256
|
Example:
|
223
257
|
'Predicted 150+ citations via integration into MMEngine (Alibaba OpenMMLab)'"""
|
224
258
|
|
259
|
+
bibtex_cite_key: str
|
260
|
+
"""Bibtex cite_key of the original article."""
|
261
|
+
|
262
|
+
def update_cite_key(self, new_cite_key: str) -> Self:
|
263
|
+
"""Update the bibtex_cite_key of the article."""
|
264
|
+
self.bibtex_cite_key = new_cite_key
|
265
|
+
return self
|
266
|
+
|
225
267
|
def _prepare_vectorization_inner(self) -> str:
|
226
268
|
return self.model_dump_json()
|
@@ -1,13 +1,14 @@
|
|
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
10
|
ChapterBase,
|
11
|
+
Patch,
|
11
12
|
SectionBase,
|
12
13
|
SubSectionBase,
|
13
14
|
)
|
@@ -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
|
|
@@ -81,6 +86,14 @@ class Article(
|
|
81
86
|
aiming to provide a comprehensive model for academic papers.
|
82
87
|
"""
|
83
88
|
|
89
|
+
def _as_prompt_inner(self) -> Dict[str, str]:
|
90
|
+
return {
|
91
|
+
"Original Article Briefing": self.referenced.referenced.referenced,
|
92
|
+
"Original Article Proposal": self.referenced.referenced.display(),
|
93
|
+
"Original Article Outline": self.referenced.display(),
|
94
|
+
"Original Article": self.display(),
|
95
|
+
}
|
96
|
+
|
84
97
|
@override
|
85
98
|
def iter_subsections(self) -> Generator[Tuple[ArticleChapter, ArticleSection, ArticleSubsection], None, None]:
|
86
99
|
return super().iter_subsections()
|
@@ -1,5 +1,7 @@
|
|
1
1
|
"""A module containing the ArticleOutline class, which represents the outline of an academic paper."""
|
2
2
|
|
3
|
+
from typing import Dict
|
4
|
+
|
3
5
|
from fabricatio.models.extra.article_base import (
|
4
6
|
ArticleBase,
|
5
7
|
ChapterBase,
|
@@ -30,3 +32,10 @@ class ArticleOutline(
|
|
30
32
|
ArticleBase[ArticleChapterOutline],
|
31
33
|
):
|
32
34
|
"""Outline of an academic paper, containing chapters, sections, subsections."""
|
35
|
+
|
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(),
|
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 {
|
48
|
+
return {
|
49
|
+
"ArticleBriefing": self.referenced,
|
50
|
+
"ArticleProposal": self.display(),
|
51
|
+
}
|
fabricatio/models/generic.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
"""This module defines generic classes for models in the Fabricatio library."""
|
2
2
|
|
3
3
|
from abc import ABC, abstractmethod
|
4
|
+
from datetime import datetime
|
4
5
|
from pathlib import Path
|
5
6
|
from typing import Any, Callable, Dict, Iterable, List, Optional, Self, Union, final, overload
|
6
7
|
|
@@ -93,7 +94,9 @@ class WithRef[T](Base):
|
|
93
94
|
@property
|
94
95
|
def referenced(self) -> T:
|
95
96
|
"""Get the referenced object."""
|
96
|
-
return ok(
|
97
|
+
return ok(
|
98
|
+
self._reference, f"`{self.__class__.__name__}`' s `_reference` field is None. Have you called `update_ref`?"
|
99
|
+
)
|
97
100
|
|
98
101
|
def update_ref[S: "WithRef"](self: S, reference: T | S) -> S: # noqa: PYI019
|
99
102
|
"""Update the reference of the object."""
|
@@ -118,17 +121,27 @@ class PersistentAble(Base):
|
|
118
121
|
"""
|
119
122
|
p = Path(path)
|
120
123
|
out = self.model_dump_json(indent=1)
|
124
|
+
|
125
|
+
# Generate a timestamp in the format YYYYMMDD_HHMMSS
|
126
|
+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
127
|
+
|
128
|
+
# Generate the hash
|
129
|
+
file_hash = blake3_hash(out.encode())[:6]
|
130
|
+
|
131
|
+
# Construct the file name with timestamp and hash
|
132
|
+
file_name = f"{self.__class__.__name__}_{timestamp}_{file_hash}.json"
|
133
|
+
|
121
134
|
if p.is_dir():
|
122
|
-
p.joinpath(
|
123
|
-
|
124
|
-
)
|
125
|
-
|
126
|
-
|
127
|
-
p.
|
128
|
-
logger.info(f"Persisted {self} to {p.as_posix()}")
|
135
|
+
p.joinpath(file_name).write_text(out, encoding="utf-8")
|
136
|
+
else:
|
137
|
+
p.mkdir(exist_ok=True, parents=True)
|
138
|
+
p.write_text(out, encoding="utf-8")
|
139
|
+
|
140
|
+
logger.info(f"Persisted `{self.__class__.__name__}` to {p.as_posix()}")
|
129
141
|
return self
|
130
142
|
|
131
|
-
|
143
|
+
@classmethod
|
144
|
+
def from_persistent(cls, path: str | Path) -> Self:
|
132
145
|
"""Load the object from a file.
|
133
146
|
|
134
147
|
Args:
|
@@ -137,7 +150,7 @@ class PersistentAble(Base):
|
|
137
150
|
Returns:
|
138
151
|
Self: The current instance of the object.
|
139
152
|
"""
|
140
|
-
return
|
153
|
+
return cls.model_validate_json(Path(path).read_text(encoding="utf-8"))
|
141
154
|
|
142
155
|
|
143
156
|
class ModelHash(Base):
|
@@ -308,7 +321,7 @@ class ProposedAble(CreateJsonObjPrompt, InstantiateFromString):
|
|
308
321
|
"""Class that provides a method to propose a JSON object based on the requirement."""
|
309
322
|
|
310
323
|
|
311
|
-
class ProposedUpdateAble(
|
324
|
+
class ProposedUpdateAble(ProposedAble, UpdateFrom, ABC):
|
312
325
|
"""Make the obj can be updated from the proposed obj in place."""
|
313
326
|
|
314
327
|
|
Binary file
|
@@ -1,47 +1,49 @@
|
|
1
|
-
fabricatio-0.2.8.
|
2
|
-
fabricatio-0.2.8.
|
3
|
-
fabricatio-0.2.8.
|
1
|
+
fabricatio-0.2.8.dev2.dist-info/METADATA,sha256=WNFO2KnmBYDfJUfDNuvTaEpTEqeX02MNbmWA4FP7Zco,5122
|
2
|
+
fabricatio-0.2.8.dev2.dist-info/WHEEL,sha256=7FgAcpQES0h1xhfN9Ugve9FTUilU6sRAr1WJ5ph2cuw,108
|
3
|
+
fabricatio-0.2.8.dev2.dist-info/licenses/LICENSE,sha256=yDZaTLnOi03bi3Dk6f5IjhLUc5old2yOsihHWU0z-i0,1067
|
4
4
|
fabricatio/decorators.py,sha256=GrkclNTGT2bk7cjTyuca7mqSVlKwTcujcj3uBuZpT8s,7343
|
5
5
|
fabricatio/core.py,sha256=MaEKZ6DDmbdScAY-7F1gwGA6fr7ADX6Mz5rNVi2msFA,6277
|
6
|
-
fabricatio/models/generic.py,sha256=
|
6
|
+
fabricatio/models/generic.py,sha256=lGwngVLqhUYDdNub0V-JgAd6ePBaBF-7Vg5who72VBc,19074
|
7
7
|
fabricatio/models/tool.py,sha256=ifivEnYiEUtjeRxQkX8vjfyzn1m1acgfrsABbQqCsGs,6912
|
8
8
|
fabricatio/models/role.py,sha256=UgIfGdfIBu4cOug8Nm1a04JCEwjXR_MDZUQhumwMptk,2710
|
9
9
|
fabricatio/models/kwargs_types.py,sha256=2tiApAy8JvpkDWKk_26_X1_g08mcHHKQz3c8pCd73x0,5286
|
10
10
|
fabricatio/models/utils.py,sha256=MYwUmvr2P2F4Q3b73IUft2D8WG5FN3hMHLBXKtru0kU,5678
|
11
|
-
fabricatio/models/extra/article_proposal.py,sha256=
|
12
|
-
fabricatio/models/extra/
|
13
|
-
fabricatio/models/extra/
|
14
|
-
fabricatio/models/extra/
|
15
|
-
fabricatio/models/extra/
|
11
|
+
fabricatio/models/extra/article_proposal.py,sha256=hPkc2bfalTwdDiCpwpQ0KVbBWINBFOrsY0-WaufohCU,1992
|
12
|
+
fabricatio/models/extra/advanced_judge.py,sha256=N0nyzIj-Zz3Edxmt79wgdd05nk9ddnVFPvNXmPGUTR8,881
|
13
|
+
fabricatio/models/extra/article_main.py,sha256=TEElG2eRnY6NCb02O7BHUISxPfmB3KT4HRQCKzB5OoA,7998
|
14
|
+
fabricatio/models/extra/article_essence.py,sha256=sKXn_Itm03ikEMQZqB8w0bgX8pl6n66qWTvL5Q9jk1g,10538
|
15
|
+
fabricatio/models/extra/article_outline.py,sha256=EMKo4CBxU3ns6UhM1eDtoo-14MjEKT7cFs_CqrXbEhU,1409
|
16
|
+
fabricatio/models/extra/article_base.py,sha256=M3icbgJ64NlqR6au6-UK9GQejz7XzE3Z1YP_8nP6VDY,15484
|
16
17
|
fabricatio/models/usages.py,sha256=1TJ-wzMtPKIH1hYhWliv-IfjxUVvbJIdj5BO0_4nRy0,31003
|
17
18
|
fabricatio/models/events.py,sha256=UvOc6V3vfjKuvh7irDezJ8EGpsNo5yzLdq4xQexVonw,4063
|
18
19
|
fabricatio/models/task.py,sha256=-EnzpEyM6Z687gF1lPcmA2szEUw6dFpu3lOtseaz95o,10193
|
19
|
-
fabricatio/models/action.py,sha256=
|
20
|
+
fabricatio/models/action.py,sha256=1tZZOcUghcmCf-YRHZLztGXHo3pHg6bKoQcBrNrvDSA,8741
|
20
21
|
fabricatio/toolboxes/fs.py,sha256=OQMdeokYxSNVrCZJAweJ0cYiK4k2QuEiNdIbS5IHIV8,705
|
21
22
|
fabricatio/toolboxes/__init__.py,sha256=dYm_Gd8XolSU_h4wnkA09dlaLDK146eeFz0CUgPZ8_c,380
|
22
23
|
fabricatio/toolboxes/arithmetic.py,sha256=sSTPkKI6-mb278DwQKFO9jKyzc9kCx45xNH7V6bGBpE,1307
|
23
24
|
fabricatio/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
24
25
|
fabricatio/fs/readers.py,sha256=5bLlpqcdhIwWfysh7gvfVv0PPPVAeDlTPGwNTio6j9M,1156
|
25
|
-
fabricatio/fs/curd.py,sha256=
|
26
|
+
fabricatio/fs/curd.py,sha256=QqwnyLdVALNnerYGXf6a0irqoPSNE9_GJV9bJ33kbl0,4610
|
26
27
|
fabricatio/fs/__init__.py,sha256=hTuYtzmvIGtbg7PTdoqLEQJ0E63hOzZltCIrLlDKaSE,559
|
27
28
|
fabricatio/config.py,sha256=o_lbhLJgkdxIkonLsAw2-zc2pntTui1CZmSvXMGASpc,16507
|
28
29
|
fabricatio/journal.py,sha256=Op0wC-JlZumnAc_aDmYM4ljnSNLoKEEMfcIRbCF69ow,455
|
29
30
|
fabricatio/__init__.py,sha256=6EjK4SxbnvFxdO9ftkXD9rxSuoPEIITNzUkuMO9s3yU,1092
|
30
|
-
fabricatio/actions/output.py,sha256=
|
31
|
-
fabricatio/actions/article_rag.py,sha256=
|
31
|
+
fabricatio/actions/output.py,sha256=wq3qZeWfiP804EWdBbJxKvuUjZ2anHA5u_Ydv8iw4dY,3528
|
32
|
+
fabricatio/actions/article_rag.py,sha256=NfyMsRYNgXMV0DepaiKbEiSdCA5uDwzld3yZxtBh2pw,3705
|
32
33
|
fabricatio/actions/rag.py,sha256=Tsjn9IkO8OlKlhBBnk7J6qh9st61jzD6SUYClGhYs7I,2686
|
33
|
-
fabricatio/actions/article.py,sha256=
|
34
|
+
fabricatio/actions/article.py,sha256=0suvbfYnmEblkbzmHNAuvZ8i_D7mJlJVcij5aaM2150,12830
|
34
35
|
fabricatio/_rust_instances.py,sha256=bQmlhUCcxTmRgvw1SfzYzNNpgW_UCjmkYw5f-VPAyg8,304
|
35
36
|
fabricatio/workflows/articles.py,sha256=oHNV5kNKEcOKP55FA7I1SlxQRlk6N26cpem_QYu05g0,1021
|
36
37
|
fabricatio/workflows/rag.py,sha256=uOZXprD479fUhLA6sYvEM8RWcVcUZXXtP0xRbTMPdHE,509
|
37
38
|
fabricatio/parser.py,sha256=OV6bIAfLJ-GfaKoTeIOqS3X3GqCgyvzSJsgYMO3ogj4,6100
|
39
|
+
fabricatio/capabilities/advanced_judge.py,sha256=bvb8fYoiKoGlBwMZVMflVE9R2MoS1VtmZAo65jMJFew,683
|
38
40
|
fabricatio/capabilities/correct.py,sha256=t9H-5FmbK78ahh0LhS4FAuOTw5qTkgkwIuBolkzYeBI,7104
|
39
41
|
fabricatio/capabilities/rag.py,sha256=FsjaMKeFgl-kBmUGDfkWn2Sa9Gp1AfOWpOZRZXZlNFY,17270
|
40
|
-
fabricatio/capabilities/rating.py,sha256=
|
41
|
-
fabricatio/capabilities/review.py,sha256=
|
42
|
+
fabricatio/capabilities/rating.py,sha256=eH9nxA2LnrXJSlZurP6PJzoIIIuj0vymIOVOPMxdDYA,14552
|
43
|
+
fabricatio/capabilities/review.py,sha256=shXINMqiWbwROCQjBp3LVTvfKBhUkeq6LTpNhgy1z6Y,11095
|
42
44
|
fabricatio/capabilities/propose.py,sha256=4QvONVVUp1rs34Te2Rjams6NioEt6FhEAxDWiveQnSg,1544
|
43
45
|
fabricatio/capabilities/task.py,sha256=5XUxYNkPIHKm-Q0_oCeEqS-i3kfq9twHqcDiZL0rKVo,4526
|
44
|
-
fabricatio/_rust.pyi,sha256=
|
45
|
-
fabricatio/_rust.cpython-312-x86_64-linux-gnu.so,sha256=
|
46
|
-
fabricatio-0.2.8.
|
47
|
-
fabricatio-0.2.8.
|
46
|
+
fabricatio/_rust.pyi,sha256=EAFwyMO99EnW2bZvZPWLRYsJpWYEZSuex86IhfANWHY,4929
|
47
|
+
fabricatio/_rust.cpython-312-x86_64-linux-gnu.so,sha256=ls1CFomHDbJJPgKtybXyG40iXkuv6-HisOksMjm9A70,1962488
|
48
|
+
fabricatio-0.2.8.dev2.data/scripts/tdown,sha256=fRnbNXbWK0TZwVR5bNvDSoijRc2r5ixc8iyU7e63D2A,4605176
|
49
|
+
fabricatio-0.2.8.dev2.dist-info/RECORD,,
|
Binary file
|
File without changes
|
File without changes
|