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.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
+ """
@@ -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
- ArticleEssence,
43
- contents,
44
- system_message=f"# your personal briefing: \n{self.briefing}",
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 GenerateOutline(Action):
92
- """Generate the article based on the outline."""
110
+ class GenerateInitialOutline(Action):
111
+ """Generate the initial article outline based on the article proposal."""
93
112
 
94
- output_key: str = "article_outline"
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
- out = ok(
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 := out.find_introspected():
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{out.display()}\n# Error Need to be fixed\n{err}",
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=False,
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 := out.find_illegal_ref():
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{out.display()}\n# Error Need to be fixed\n{err}\n\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=False,
202
+ supervisor_check=supervisor_check,
156
203
  )
157
204
  )
158
- return out.update_ref(article_proposal)
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=False,
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 typing import Optional
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.extra.article_outline import ArticleOutline
8
+ from fabricatio.models.extra.article_main import Article, ArticleParagraphPatch, ArticleSubsection
9
+ from fabricatio.models.utils import ok
10
10
 
11
11
 
12
- class GenerateArticleRAG(Action, RAG):
12
+ class TweakArticleRAG(Action, RAG):
13
13
  """Write an article based on the provided outline."""
14
14
 
15
- output_key: str = "article"
15
+ output_key: str = "rag_tweaked_article"
16
16
 
17
- async def _execute(self, article_outline: ArticleOutline, **cxt) -> Optional[Article]:
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
- logger.info(f"Writing an article based on the outline:\n{article_outline.title}")
20
- refined_q = await self.arefined_query(article_outline.display())
21
- return await self.propose(
22
- Article,
23
- article_outline.display(),
24
- **self.prepend_sys_msg(f"{await self.aretrieve_compact(refined_q)}\n{self.briefing}"),
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
- class WriteArticleFineGrind(Action, RAG):
29
- """Fine-grind an article based on the provided outline."""
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
- output_key: str = "article"
61
+ return article
32
62
 
33
- async def _execute(self, article_outline: ArticleOutline, **cxt) -> Optional[Article]:
34
- """Fine-grind an article based on the provided outline."""
35
- logger.info(f"Fine-grinding an article based on the outline:\n{article_outline.title}")
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
+ )
@@ -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
- persist_dir.mkdir(parents=True, exist_ok=True)
64
- for v in cxt.values():
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(persist_dir)
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 GiveRating(WithBriefing, LLMUsage):
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 GiveRating
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(GiveRating, Propose):
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}")]
@@ -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: {current_action}")
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: {step.output_key}")
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
- latex_code: str
24
- """LaTeX representation following academic typesetting standards:
25
- - Must use equation environment (e.g., `equation`, `align`).
26
- - Multiline equations must align at '=' using `&`.
27
- - Include unit annotations where applicable.
28
- Example: "\\begin{equation} \\mathcal{L}_{NAS} = \\alpha \\|\\theta\\|_2 + \\beta H(p) \\end{equation}"
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
- """Semantic fingerprint of academic paper for structured analysis.
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
- Encodes research artifacts with dual human-machine interpretability.
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
- """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"""
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 {"ArticleBriefing": self.referenced, "ArticleProposal": self.display()}
48
+ return {
49
+ "ArticleBriefing": self.referenced,
50
+ "ArticleProposal": self.display(),
51
+ }
@@ -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(self._reference, "_reference is None")
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(f"{self.__class__.__name__}_{blake3_hash(out.encode())[:6]}.json").write_text(
123
- out, encoding="utf-8"
124
- )
125
- return self
126
- p.mkdir(exist_ok=True, parents=True)
127
- p.write_text(out, encoding="utf-8")
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
- def from_persistent(self, path: str | Path) -> Self:
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 self.model_validate_json(Path(path).read_text(encoding="utf-8"))
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(PersistentAble, UpdateFrom, ABC):
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fabricatio
3
- Version: 0.2.8.dev0
3
+ Version: 0.2.8.dev2
4
4
  Classifier: License :: OSI Approved :: MIT License
5
5
  Classifier: Programming Language :: Rust
6
6
  Classifier: Programming Language :: Python :: 3.12
@@ -1,47 +1,49 @@
1
- fabricatio-0.2.8.dev0.dist-info/METADATA,sha256=jgTrZJZiqFyLRjwYSr96zd6uT0LKFrsao5BS5GTw49Q,5122
2
- fabricatio-0.2.8.dev0.dist-info/WHEEL,sha256=7FgAcpQES0h1xhfN9Ugve9FTUilU6sRAr1WJ5ph2cuw,108
3
- fabricatio-0.2.8.dev0.dist-info/licenses/LICENSE,sha256=yDZaTLnOi03bi3Dk6f5IjhLUc5old2yOsihHWU0z-i0,1067
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=gbm1BnJqhdw42rx2Dcq1f13EnLVUKqFOJB_LxQhQg3M,18664
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=UGH55J6T4oR6tPiOxP4nmUIXavBHUOURKlibT2PiQn0,1365
12
- fabricatio/models/extra/article_main.py,sha256=ssh8FWo5HzOdm77LArsQzv61yg3CBKMSxtctjYbmxM4,7519
13
- fabricatio/models/extra/article_essence.py,sha256=q80VKO11QONkounDL98IpfG6DSC8ymfm7iQiWkzp3rY,9003
14
- fabricatio/models/extra/article_outline.py,sha256=aiqPCB4j-m3dl5n3R7gn_Idqx5kST1hbnGZhondz2DA,1113
15
- fabricatio/models/extra/article_base.py,sha256=hekBRwPGg1fyGwCqW2n-EU1OjVc3QXsWElaBymo7F_k,14888
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=yEYayK_gNtggpVgWlQ4K4wCHPqlhkouhUKW1SsJoR20,8646
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=FuG75qco4dX8vhIK27gKz9rKUXbWHOFg5yK3nGLB25s,4469
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=22IwSPukxFT_Yf0rdEBuUFKTfUipOLx_ZieW0PHAlkI,2246
31
- fabricatio/actions/article_rag.py,sha256=jAoFU75vZ-jFROGh4bZKmvY10K9zJPLqzeEa7wSiwu8,1421
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=Oi67XUw_lE4Fdb6RzrgdbEdFBG4WutPRQQWBk5HbOms,8077
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=K6dIaMDMWNUhCenuP_lFriaofj6gBPjfNXEILp5yzjU,14556
41
- fabricatio/capabilities/review.py,sha256=_m7uGNfhW7iDhcCJrLiSBmEvMq56fpPIzNGh1X20YZM,11103
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=n6mFYqLQlyfumJZQ_E3SesR_yLrjfRLjf6N1VdlF6U8,3707
45
- fabricatio/_rust.cpython-312-x86_64-linux-gnu.so,sha256=wQr2FLieZwAKIXasejND5CX7Y4-vhRHwqI8ds00bK9Y,1916040
46
- fabricatio-0.2.8.dev0.data/scripts/tdown,sha256=zC3ne1G7HqaXSJ2QJlv0ILXfKgT758L15JvGfbiC1gE,4588888
47
- fabricatio-0.2.8.dev0.dist-info/RECORD,,
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