fabricatio 0.3.14.dev8__cp313-cp313-manylinux_2_34_x86_64.whl → 0.3.15.dev4__cp313-cp313-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/actions/article.py +115 -19
- fabricatio/models/extra/article_base.py +96 -32
- fabricatio/models/extra/article_main.py +8 -3
- fabricatio/models/generic.py +1 -1
- fabricatio/rust.cpython-313-x86_64-linux-gnu.so +0 -0
- fabricatio/rust.pyi +13 -0
- fabricatio-0.3.15.dev4.data/scripts/tdown +0 -0
- fabricatio-0.3.15.dev4.data/scripts/ttm +0 -0
- {fabricatio-0.3.14.dev8.dist-info → fabricatio-0.3.15.dev4.dist-info}/METADATA +2 -1
- {fabricatio-0.3.14.dev8.dist-info → fabricatio-0.3.15.dev4.dist-info}/RECORD +12 -12
- fabricatio-0.3.14.dev8.data/scripts/tdown +0 -0
- fabricatio-0.3.14.dev8.data/scripts/ttm +0 -0
- {fabricatio-0.3.14.dev8.dist-info → fabricatio-0.3.15.dev4.dist-info}/WHEEL +0 -0
- {fabricatio-0.3.14.dev8.dist-info → fabricatio-0.3.15.dev4.dist-info}/licenses/LICENSE +0 -0
fabricatio/actions/article.py
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
from asyncio import gather
|
4
4
|
from pathlib import Path
|
5
|
-
from typing import Callable, List, Optional
|
5
|
+
from typing import Callable, ClassVar, List, Optional
|
6
6
|
|
7
7
|
from more_itertools import filter_map
|
8
8
|
from pydantic import Field
|
@@ -15,14 +15,14 @@ from fabricatio.fs import dump_text, safe_text_read
|
|
15
15
|
from fabricatio.journal import logger
|
16
16
|
from fabricatio.models.action import Action
|
17
17
|
from fabricatio.models.extra.article_essence import ArticleEssence
|
18
|
-
from fabricatio.models.extra.article_main import Article
|
18
|
+
from fabricatio.models.extra.article_main import Article, ArticleChapter, ArticleSubsection
|
19
19
|
from fabricatio.models.extra.article_outline import ArticleOutline
|
20
20
|
from fabricatio.models.extra.article_proposal import ArticleProposal
|
21
21
|
from fabricatio.models.extra.rule import RuleSet
|
22
22
|
from fabricatio.models.kwargs_types import ValidateKwargs
|
23
23
|
from fabricatio.models.task import Task
|
24
24
|
from fabricatio.models.usages import LLMUsage
|
25
|
-
from fabricatio.rust import CONFIG, TEMPLATE_MANAGER, BibManager, detect_language
|
25
|
+
from fabricatio.rust import CONFIG, TEMPLATE_MANAGER, BibManager, detect_language, word_count
|
26
26
|
from fabricatio.utils import ok, wrapp_in_block
|
27
27
|
|
28
28
|
|
@@ -277,43 +277,139 @@ class LoadArticle(Action):
|
|
277
277
|
class WriteChapterSummary(Action, LLMUsage):
|
278
278
|
"""Write the chapter summary."""
|
279
279
|
|
280
|
-
|
280
|
+
ctx_override: ClassVar[bool] = True
|
281
281
|
|
282
282
|
paragraph_count: int = 1
|
283
|
+
"""The number of paragraphs to generate in the chapter summary."""
|
283
284
|
|
284
|
-
summary_word_count: int =
|
285
|
-
|
285
|
+
summary_word_count: int = 120
|
286
|
+
"""The number of words to use in each chapter summary."""
|
287
|
+
output_key: str = "summarized_article"
|
288
|
+
"""The key under which the summarized article will be stored in the output."""
|
286
289
|
summary_title: str = "Chapter Summary"
|
287
|
-
|
290
|
+
"""The title to be used for the generated chapter summary section."""
|
291
|
+
|
292
|
+
skip_chapters: List[str] = Field(default_factory=list)
|
293
|
+
"""A list of chapter titles to skip during summary generation."""
|
294
|
+
|
295
|
+
async def _execute(self, article_path: Path, **cxt) -> Article:
|
296
|
+
article = Article.from_article_file(article_path, article_path.stem)
|
297
|
+
|
298
|
+
chaps = [c for c in article.chapters if c.title not in self.skip_chapters]
|
299
|
+
|
300
|
+
retained_chapters = []
|
301
|
+
# Count chapters before filtering based on section presence,
|
302
|
+
# chaps at this point has already been filtered by self.skip_chapters
|
303
|
+
initial_chaps_for_summary_step_count = len(chaps)
|
304
|
+
|
305
|
+
for chapter_candidate in chaps:
|
306
|
+
if chapter_candidate.sections: # Check if the sections list is non-empty
|
307
|
+
retained_chapters.append(chapter_candidate)
|
308
|
+
else:
|
309
|
+
# Log c warning for each chapter skipped due to lack of sections
|
310
|
+
logger.warning(
|
311
|
+
f"Chapter '{chapter_candidate.title}' has no sections and will be skipped for summary generation."
|
312
|
+
)
|
313
|
+
|
314
|
+
chaps = retained_chapters # Update chaps to only include chapters with sections
|
288
315
|
|
289
|
-
|
290
|
-
|
316
|
+
# If chaps is now empty, but there were chapters to consider at the start of this step,
|
317
|
+
# log c specific warning.
|
318
|
+
if not chaps and initial_chaps_for_summary_step_count > 0:
|
319
|
+
raise ValueError("No chapters with sections were found. Please check your input data.")
|
291
320
|
|
321
|
+
# This line was part of the original selection.
|
322
|
+
# It will now log the titles of the chapters that are actually being processed (those with sections).
|
323
|
+
# If 'chaps' is empty, this will result in logger.info(""), which is acceptable.
|
324
|
+
logger.info(";".join(a.title for a in chaps))
|
292
325
|
ret = [
|
293
|
-
|
326
|
+
ArticleSubsection.from_typst_code(self.summary_title, raw)
|
294
327
|
for raw in (
|
295
328
|
await self.aask(
|
296
329
|
TEMPLATE_MANAGER.render_template(
|
297
330
|
CONFIG.templates.chap_summary_template,
|
298
331
|
[
|
299
332
|
{
|
300
|
-
"chapter":
|
301
|
-
"title":
|
302
|
-
"language":
|
333
|
+
"chapter": c.to_typst_code(),
|
334
|
+
"title": c.title,
|
335
|
+
"language": c.language,
|
303
336
|
"summary_word_count": self.summary_word_count,
|
304
337
|
"paragraph_count": self.paragraph_count,
|
305
338
|
}
|
306
|
-
for
|
339
|
+
for c in chaps
|
307
340
|
],
|
308
341
|
)
|
309
342
|
)
|
310
343
|
)
|
311
344
|
]
|
312
345
|
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
346
|
+
for c, n in zip(chaps, ret, strict=True):
|
347
|
+
c: ArticleChapter
|
348
|
+
n: ArticleSubsection
|
349
|
+
if c.sections[-1].title == self.summary_title:
|
350
|
+
logger.debug(f"Removing old summary `{self.summary_title}` at {c.title}")
|
351
|
+
c.sections.pop()
|
352
|
+
|
353
|
+
c.sections[-1].subsections.append(n)
|
354
|
+
|
355
|
+
article.update_article_file(article_path)
|
356
|
+
|
357
|
+
dump_text(
|
358
|
+
article_path, safe_text_read(article_path).replace(f"=== {self.summary_title}", f"== {self.summary_title}")
|
359
|
+
)
|
360
|
+
return article
|
361
|
+
|
362
|
+
|
363
|
+
class WriteResearchContentSummary(Action, LLMUsage):
|
364
|
+
"""Write the research content summary."""
|
365
|
+
|
366
|
+
ctx_override: ClassVar[bool] = True
|
367
|
+
summary_word_count: int = 160
|
368
|
+
"""The number of words to use in the research content summary."""
|
369
|
+
|
370
|
+
output_key: str = "summarized_article"
|
371
|
+
"""The key under which the summarized article will be stored in the output."""
|
372
|
+
|
373
|
+
summary_title: str = "Research Content"
|
374
|
+
"""The title to be used for the generated research content summary section."""
|
375
|
+
|
376
|
+
paragraph_count: int = 1
|
377
|
+
"""The number of paragraphs to generate in the research content summary."""
|
378
|
+
|
379
|
+
async def _execute(self, article_path: Path, **cxt) -> Article:
|
380
|
+
article = Article.from_article_file(article_path, article_path.stem)
|
381
|
+
if not article.chapters:
|
382
|
+
raise ValueError("No chapters found in the article.")
|
383
|
+
chap_1 = article.chapters[0]
|
384
|
+
if not chap_1.sections:
|
385
|
+
raise ValueError("No sections found in the first chapter of the article.")
|
386
|
+
|
387
|
+
outline = article.extrac_outline()
|
388
|
+
suma: str = await self.aask(
|
389
|
+
TEMPLATE_MANAGER.render_template(
|
390
|
+
CONFIG.templates.research_content_summary_template,
|
391
|
+
{
|
392
|
+
"title": outline.title,
|
393
|
+
"outline": outline.to_typst_code(),
|
394
|
+
"language": detect_language(self.summary_title),
|
395
|
+
"summary_word_count": self.summary_word_count,
|
396
|
+
"paragraph_count": self.paragraph_count,
|
397
|
+
},
|
317
398
|
)
|
399
|
+
)
|
400
|
+
logger.success(
|
401
|
+
f"{self.summary_title}|Wordcount: {word_count(suma)}|Expected: {self.summary_word_count}\n{suma}"
|
402
|
+
)
|
403
|
+
|
404
|
+
if chap_1.sections[-1].title == self.summary_title:
|
405
|
+
# remove old
|
406
|
+
logger.debug(f"Removing old summary `{self.summary_title}`")
|
407
|
+
chap_1.sections.pop()
|
318
408
|
|
319
|
-
|
409
|
+
chap_1.sections[-1].subsections.append(ArticleSubsection.from_typst_code(self.summary_title, suma))
|
410
|
+
|
411
|
+
article.update_article_file(article_path)
|
412
|
+
dump_text(
|
413
|
+
article_path, safe_text_read(article_path).replace(f"=== {self.summary_title}", f"== {self.summary_title}")
|
414
|
+
)
|
415
|
+
return article
|
@@ -21,7 +21,15 @@ from fabricatio.models.generic import (
|
|
21
21
|
Titled,
|
22
22
|
WordCount,
|
23
23
|
)
|
24
|
-
from fabricatio.rust import
|
24
|
+
from fabricatio.rust import (
|
25
|
+
detect_language,
|
26
|
+
extract_body,
|
27
|
+
replace_thesis_body,
|
28
|
+
split_out_metadata,
|
29
|
+
strip_comment,
|
30
|
+
to_metadata,
|
31
|
+
word_count,
|
32
|
+
)
|
25
33
|
from fabricatio.utils import fallback_kwargs, ok
|
26
34
|
from pydantic import Field
|
27
35
|
|
@@ -52,10 +60,31 @@ class ArticleMetaData(SketchedAble, Described, WordCount, Titled, Language):
|
|
52
60
|
aims: List[str]
|
53
61
|
"""List of writing aims of the research component in academic style."""
|
54
62
|
|
63
|
+
_unstructured_body: str = ""
|
64
|
+
"""Store the source of the unknown information."""
|
65
|
+
|
55
66
|
@property
|
56
67
|
def typst_metadata_comment(self) -> str:
|
57
68
|
"""Generates a comment for the metadata of the article component."""
|
58
|
-
|
69
|
+
data = self.model_dump(
|
70
|
+
include={"description", "aims", "expected_word_count"},
|
71
|
+
by_alias=True,
|
72
|
+
)
|
73
|
+
return to_metadata({k: v for k, v in data.items() if v})
|
74
|
+
|
75
|
+
@property
|
76
|
+
def unstructured_body(self) -> str:
|
77
|
+
"""Returns the unstructured body of the article component."""
|
78
|
+
return self._unstructured_body
|
79
|
+
|
80
|
+
def update_unstructured_body[S: "ArticleMetaData"](self: S, body: str) -> S:
|
81
|
+
"""Update the unstructured body of the article component."""
|
82
|
+
self._unstructured_body = body
|
83
|
+
return self
|
84
|
+
|
85
|
+
@property
|
86
|
+
def language(self) -> str:
|
87
|
+
return detect_language(self.title)
|
59
88
|
|
60
89
|
|
61
90
|
class FromTypstCode(ArticleMetaData):
|
@@ -67,13 +96,8 @@ class FromTypstCode(ArticleMetaData):
|
|
67
96
|
data, body = split_out_metadata(body)
|
68
97
|
|
69
98
|
return cls(
|
70
|
-
heading=title,
|
71
|
-
**fallback_kwargs(
|
72
|
-
data or {},
|
73
|
-
elaboration="",
|
74
|
-
expected_word_count=word_count(body),
|
75
|
-
aims=[],
|
76
|
-
),
|
99
|
+
heading=title.strip(),
|
100
|
+
**fallback_kwargs(data or {}, elaboration="", expected_word_count=word_count(body), aims=[]),
|
77
101
|
**kwargs,
|
78
102
|
)
|
79
103
|
|
@@ -83,7 +107,7 @@ class ToTypstCode(ArticleMetaData):
|
|
83
107
|
|
84
108
|
def to_typst_code(self) -> str:
|
85
109
|
"""Converts the component into a Typst code snippet for rendering."""
|
86
|
-
return f"{self.title}\n{self.typst_metadata_comment}\n"
|
110
|
+
return f"{self.title}\n{self.typst_metadata_comment}\n\n{self._unstructured_body}"
|
87
111
|
|
88
112
|
|
89
113
|
class ArticleOutlineBase(
|
@@ -151,12 +175,16 @@ class SectionBase[T: SubSectionBase](ArticleOutlineBase):
|
|
151
175
|
@classmethod
|
152
176
|
def from_typst_code(cls, title: str, body: str, **kwargs) -> Self:
|
153
177
|
"""Creates an Article object from the given Typst code."""
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
178
|
+
raw = extract_sections(body, level=3, section_char="=")
|
179
|
+
|
180
|
+
return (
|
181
|
+
super()
|
182
|
+
.from_typst_code(
|
183
|
+
title,
|
184
|
+
body,
|
185
|
+
subsections=[cls.child_type.from_typst_code(*pack) for pack in raw],
|
186
|
+
)
|
187
|
+
.update_unstructured_body("" if raw else strip_comment(body))
|
160
188
|
)
|
161
189
|
|
162
190
|
def resolve_update_conflict(self, other: Self) -> str:
|
@@ -191,6 +219,11 @@ class SectionBase[T: SubSectionBase](ArticleOutlineBase):
|
|
191
219
|
return f"Section `{self.title}` contains no subsections, expected at least one, but got 0, you can add one or more as needed."
|
192
220
|
return ""
|
193
221
|
|
222
|
+
@property
|
223
|
+
def exact_word_count(self) -> int:
|
224
|
+
"""Returns the exact word count of the article section outline."""
|
225
|
+
return sum(a.exact_word_count for a in self.subsections)
|
226
|
+
|
194
227
|
|
195
228
|
class ChapterBase[T: SectionBase](ArticleOutlineBase):
|
196
229
|
"""Base class for article chapters."""
|
@@ -206,12 +239,16 @@ class ChapterBase[T: SectionBase](ArticleOutlineBase):
|
|
206
239
|
@classmethod
|
207
240
|
def from_typst_code(cls, title: str, body: str, **kwargs) -> Self:
|
208
241
|
"""Creates an Article object from the given Typst code."""
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
242
|
+
raw_sec = extract_sections(body, level=2, section_char="=")
|
243
|
+
|
244
|
+
return (
|
245
|
+
super()
|
246
|
+
.from_typst_code(
|
247
|
+
title,
|
248
|
+
body,
|
249
|
+
sections=[cls.child_type.from_typst_code(*pack) for pack in raw_sec],
|
250
|
+
)
|
251
|
+
.update_unstructured_body("" if raw_sec else strip_comment(body))
|
215
252
|
)
|
216
253
|
|
217
254
|
def resolve_update_conflict(self, other: Self) -> str:
|
@@ -243,6 +280,15 @@ class ChapterBase[T: SectionBase](ArticleOutlineBase):
|
|
243
280
|
return f"Chapter `{self.title}` contains no sections, expected at least one, but got 0, you can add one or more as needed."
|
244
281
|
return ""
|
245
282
|
|
283
|
+
@property
|
284
|
+
def exact_word_count(self) -> int:
|
285
|
+
"""Calculates the total word count across all sections in the chapter.
|
286
|
+
|
287
|
+
Returns:
|
288
|
+
int: The cumulative word count of all sections.
|
289
|
+
"""
|
290
|
+
return sum(a.exact_word_count for a in self.sections)
|
291
|
+
|
246
292
|
|
247
293
|
class ArticleBase[T: ChapterBase](FinalizedDumpAble, AsPrompt, FromTypstCode, ToTypstCode, ABC):
|
248
294
|
"""Base class for article outlines."""
|
@@ -263,15 +309,33 @@ class ArticleBase[T: ChapterBase](FinalizedDumpAble, AsPrompt, FromTypstCode, To
|
|
263
309
|
|
264
310
|
child_type: ClassVar[Type[ChapterBase]]
|
265
311
|
|
312
|
+
@property
|
313
|
+
def language(self) -> str:
|
314
|
+
if self.title:
|
315
|
+
return super().language
|
316
|
+
return self.chapters[0].language
|
317
|
+
|
318
|
+
@property
|
319
|
+
def exact_word_count(self) -> int:
|
320
|
+
"""Calculates the total word count across all chapters in the article.
|
321
|
+
|
322
|
+
Returns:
|
323
|
+
int: The cumulative word count of all chapters.
|
324
|
+
"""
|
325
|
+
return sum(ch.exact_word_count for ch in self.chapters)
|
326
|
+
|
266
327
|
@classmethod
|
267
328
|
def from_typst_code(cls, title: str, body: str, **kwargs) -> Self:
|
268
329
|
"""Generates an article from the given Typst code."""
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
330
|
+
raw = extract_sections(body, level=1, section_char="=")
|
331
|
+
return (
|
332
|
+
super()
|
333
|
+
.from_typst_code(
|
334
|
+
title,
|
335
|
+
body,
|
336
|
+
chapters=[cls.child_type.from_typst_code(*pack) for pack in raw],
|
337
|
+
)
|
338
|
+
.update_unstructured_body("" if raw else strip_comment(body))
|
275
339
|
)
|
276
340
|
|
277
341
|
def iter_dfs_rev(
|
@@ -350,7 +414,7 @@ class ArticleBase[T: ChapterBase](FinalizedDumpAble, AsPrompt, FromTypstCode, To
|
|
350
414
|
|
351
415
|
def to_typst_code(self) -> str:
|
352
416
|
"""Generates the Typst code representation of the article."""
|
353
|
-
return f"// #{super().to_typst_code()}\n
|
417
|
+
return f"// #Title: {super().to_typst_code()}\n" + "\n\n".join(a.to_typst_code() for a in self.chapters)
|
354
418
|
|
355
419
|
def finalized_dump(self) -> str:
|
356
420
|
"""Generates standardized hierarchical markup for academic publishing systems.
|
@@ -401,11 +465,11 @@ class ArticleBase[T: ChapterBase](FinalizedDumpAble, AsPrompt, FromTypstCode, To
|
|
401
465
|
"""Set all chap, sec, subsec have same word count sum up to be `self.expected_word_count`."""
|
402
466
|
return self.avg_chap_wordcount().avg_sec_wordcount().avg_subsec_wordcount()
|
403
467
|
|
404
|
-
def update_article_file(self, file: str | Path) ->
|
468
|
+
def update_article_file[S: "ArticleBase"](self: S, file: str | Path) -> S:
|
405
469
|
"""Update the article file."""
|
406
470
|
file = Path(file)
|
407
471
|
string = safe_text_read(file)
|
408
|
-
if updated := replace_thesis_body(string, ARTICLE_WRAPPER, self.to_typst_code()):
|
472
|
+
if updated := replace_thesis_body(string, ARTICLE_WRAPPER, f"\n\n{self.to_typst_code()}\n\n"):
|
409
473
|
dump_text(file, updated)
|
410
474
|
logger.success(f"Successfully updated {file.as_posix()}.")
|
411
475
|
else:
|
@@ -413,7 +477,7 @@ class ArticleBase[T: ChapterBase](FinalizedDumpAble, AsPrompt, FromTypstCode, To
|
|
413
477
|
return self
|
414
478
|
|
415
479
|
@classmethod
|
416
|
-
def from_article_file[S: "ArticleBase"](cls: Type[S], file: str | Path, title: str) -> S:
|
480
|
+
def from_article_file[S: "ArticleBase"](cls: Type[S], file: str | Path, title: str = "") -> S:
|
417
481
|
"""Load article from file."""
|
418
482
|
file = Path(file)
|
419
483
|
string = safe_text_read(file)
|
@@ -52,7 +52,7 @@ class Paragraph(SketchedAble, WordCount, Described):
|
|
52
52
|
return cls(elaboration="", aims=[], expected_word_count=word_count(content), content=content.strip())
|
53
53
|
|
54
54
|
@property
|
55
|
-
def
|
55
|
+
def exact_word_count(self) -> int:
|
56
56
|
"""Calculates the exact word count of the content."""
|
57
57
|
return word_count(self.content)
|
58
58
|
|
@@ -70,6 +70,11 @@ class ArticleSubsection(SubSectionBase):
|
|
70
70
|
_max_word_count_deviation: float = 0.3
|
71
71
|
"""Maximum allowed deviation from the expected word count, as a percentage."""
|
72
72
|
|
73
|
+
@property
|
74
|
+
def exact_word_count(self) -> int:
|
75
|
+
"""Calculates the exact word count of all paragraphs in the subsection."""
|
76
|
+
return sum(a.exact_word_count for a in self.paragraphs)
|
77
|
+
|
73
78
|
@property
|
74
79
|
def word_count(self) -> int:
|
75
80
|
"""Calculates the total word count of all paragraphs in the subsection."""
|
@@ -273,9 +278,9 @@ class Article(
|
|
273
278
|
err = []
|
274
279
|
for chap, sec, subsec in self.iter_subsections():
|
275
280
|
for i, p in enumerate(subsec.paragraphs):
|
276
|
-
if p.
|
281
|
+
if p.exact_word_count <= threshold:
|
277
282
|
err.append(
|
278
|
-
f"{chap.title}->{sec.title}->{subsec.title}-> Paragraph [{i}] is too short, {p.
|
283
|
+
f"{chap.title}->{sec.title}->{subsec.title}-> Paragraph [{i}] is too short, {p.exact_word_count} words."
|
279
284
|
)
|
280
285
|
|
281
286
|
return "\n".join(err)
|
fabricatio/models/generic.py
CHANGED
@@ -114,7 +114,7 @@ class WordCount(Base, ABC):
|
|
114
114
|
@property
|
115
115
|
def exact_word_count(self) -> int:
|
116
116
|
"""Get the exact word count of this research component."""
|
117
|
-
raise NotImplementedError(f"`
|
117
|
+
raise NotImplementedError(f"`exact_word_count` is not implemented for {self.__class__.__name__}")
|
118
118
|
|
119
119
|
|
120
120
|
class FromMapping:
|
Binary file
|
fabricatio/rust.pyi
CHANGED
@@ -339,6 +339,16 @@ def uncomment(string: str) -> str:
|
|
339
339
|
The string with comments (lines starting with '// ' or '//') removed.
|
340
340
|
"""
|
341
341
|
|
342
|
+
def strip_comment(string: str) -> str:
|
343
|
+
"""Remove leading and trailing comment lines from a multi-line string.
|
344
|
+
|
345
|
+
Args:
|
346
|
+
string: Input string that may have comment lines at start and/or end
|
347
|
+
|
348
|
+
Returns:
|
349
|
+
str: A new string with leading and trailing comment lines removed
|
350
|
+
"""
|
351
|
+
|
342
352
|
def split_out_metadata(string: str) -> Tuple[Optional[JsonValue], str]:
|
343
353
|
"""Split out metadata from a string.
|
344
354
|
|
@@ -494,6 +504,9 @@ class TemplateManagerConfig:
|
|
494
504
|
class TemplateConfig:
|
495
505
|
"""Template configuration structure."""
|
496
506
|
|
507
|
+
research_content_summary_template: str
|
508
|
+
"""The name of the research content summary template which will be used to generate a summary of research content."""
|
509
|
+
|
497
510
|
create_json_obj_template: str
|
498
511
|
"""The name of the create json object template which will be used to create a json object."""
|
499
512
|
|
Binary file
|
Binary file
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: fabricatio
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.15.dev4
|
4
4
|
Classifier: License :: OSI Approved :: MIT License
|
5
5
|
Classifier: Programming Language :: Rust
|
6
6
|
Classifier: Programming Language :: Python :: 3.12
|
@@ -185,4 +185,5 @@ Special thanks to the contributors and maintainers of:
|
|
185
185
|
- [PyO3](https://github.com/PyO3/pyo3)
|
186
186
|
- [Maturin](https://github.com/PyO3/maturin)
|
187
187
|
- [Handlebars.rs](https://github.com/sunng87/handlebars-rust)
|
188
|
+
- [LiteLLM](https://github.com/BerriAI/litellm)
|
188
189
|
|
@@ -1,11 +1,11 @@
|
|
1
|
-
fabricatio-0.3.
|
2
|
-
fabricatio-0.3.
|
3
|
-
fabricatio-0.3.
|
4
|
-
fabricatio-0.3.
|
5
|
-
fabricatio-0.3.
|
1
|
+
fabricatio-0.3.15.dev4.data/scripts/tdown,sha256=S4-bCA83LTAzlPRotjdov8G7PVE2yni31GBoqC2K5y0,4721520
|
2
|
+
fabricatio-0.3.15.dev4.data/scripts/ttm,sha256=QmFgMD6YmVvAqx5r6p6Hqsq4rHbP66i76sLp7LyBhUs,3919496
|
3
|
+
fabricatio-0.3.15.dev4.dist-info/METADATA,sha256=aRlHe_3Yf0BsK_1U598VD4IIWs-0l6F85axA-RsD-LU,5017
|
4
|
+
fabricatio-0.3.15.dev4.dist-info/WHEEL,sha256=OZYXF4emuP5o7uCHyen8StXv3k74AF7eDhQe1rxgOqQ,108
|
5
|
+
fabricatio-0.3.15.dev4.dist-info/licenses/LICENSE,sha256=yDZaTLnOi03bi3Dk6f5IjhLUc5old2yOsihHWU0z-i0,1067
|
6
6
|
fabricatio/__init__.py,sha256=pSLe6QL4zQGaZXfhF9KW4fa1D8chqCQm_7yInCP6Kt8,732
|
7
7
|
fabricatio/actions/__init__.py,sha256=ZMa1LeM5BNeqp-J-D32W-f5bD53-kdXGyt0zuueJofM,47
|
8
|
-
fabricatio/actions/article.py,sha256=
|
8
|
+
fabricatio/actions/article.py,sha256=DtArcKFQM1jp4f3OKPng9ciqY7TmNIUjrjCaZO3OCg8,16695
|
9
9
|
fabricatio/actions/article_rag.py,sha256=2lQogjV_1iZkbYI4C9kGGpQH9TBeIDaQCkyi7ueqFus,17582
|
10
10
|
fabricatio/actions/fs.py,sha256=nlTmk-tYDW158nz_fzlsNfuYJwj7j4BHn_MFY5hxdqs,934
|
11
11
|
fabricatio/actions/output.py,sha256=3VRwDcvimBPrf4ypxbhJd_ScJ_JYiC0ucr6vGOqs9Fc,9687
|
@@ -35,16 +35,16 @@ fabricatio/models/adv_kwargs_types.py,sha256=nmj1D0GVosZxKcdiw-B5vJB04Whr5zh30ZB
|
|
35
35
|
fabricatio/models/extra/__init__.py,sha256=0R9eZsCNu6OV-Xtf15H7FrqhfHTFBFf3fBrcd7ChsJ0,53
|
36
36
|
fabricatio/models/extra/advanced_judge.py,sha256=CKPP4Lseb_Ey8Y7i2V9HJfB-mZgCknFdqq7Zo41o6s4,1060
|
37
37
|
fabricatio/models/extra/aricle_rag.py,sha256=KaryVIaMZRV6vpUYwkHDe09tgOihVWGPb1mGs1GXKSw,11723
|
38
|
-
fabricatio/models/extra/article_base.py,sha256=
|
38
|
+
fabricatio/models/extra/article_base.py,sha256=j_3Xug4n73mL-RB5nYN5HUMgMQG7aoeIcRHiQaRY4fk,18329
|
39
39
|
fabricatio/models/extra/article_essence.py,sha256=lAkfGj4Jqiy3dSmtloVVr2krej76TV1Ky-2Fr6pNE_Q,2692
|
40
|
-
fabricatio/models/extra/article_main.py,sha256=
|
40
|
+
fabricatio/models/extra/article_main.py,sha256=WOH5KTFhtrmdgmTLt3-ojBz_OAKkQERh_ODmGcpWwdk,11021
|
41
41
|
fabricatio/models/extra/article_outline.py,sha256=71mgx66KRiXBtdYId4WNkAYp9tJ7OhUqmQyOEe7IRxI,1627
|
42
42
|
fabricatio/models/extra/article_proposal.py,sha256=7OgcsS9ujjSi_06Z1ln4SCDQgrS4xPGrtgc2dv8EzGo,1857
|
43
43
|
fabricatio/models/extra/patches.py,sha256=_ghmnlvTZQq7UJyaH77mTZE9abjvxRJ2mgWHUbezUls,977
|
44
44
|
fabricatio/models/extra/problem.py,sha256=1Sd8hsThQK6pXMXhErRhP1ft58z4PvqeB8AV8VcXiaI,7051
|
45
45
|
fabricatio/models/extra/rag.py,sha256=fwyEXOECQNe8LPUKGAxEcp9vp7o5356rna-TzGpkvnE,3869
|
46
46
|
fabricatio/models/extra/rule.py,sha256=TYtA_aSgunw8wRS3BfdNqBZbbdeS-VXLbVCJhz85Suk,2617
|
47
|
-
fabricatio/models/generic.py,sha256=
|
47
|
+
fabricatio/models/generic.py,sha256=nVQhjlxKcSdIffMAwDRDFwzbw4TA82_hXrjuFafb6eQ,27058
|
48
48
|
fabricatio/models/kwargs_types.py,sha256=VrzAJaOSlQ-xN5NIIi3k4KpIY0c9beuxcuUnF-mkEEk,3282
|
49
49
|
fabricatio/models/role.py,sha256=KxiP_hsIP85QtJhOQL_UH0lKul87hqRcd49IdWr05qQ,4154
|
50
50
|
fabricatio/models/task.py,sha256=CdR1Zbf-lZN0jODj9iriTn1X2DxLxjXlvZgy3kEd6lI,10723
|
@@ -52,8 +52,8 @@ fabricatio/models/tool.py,sha256=jYdN6FWEz6pE-vEh3H78VHDPpSttUQE79nfXOD4FE6U,120
|
|
52
52
|
fabricatio/models/usages.py,sha256=bpM-a9i-WpSOh-XL3LiYTa3AxQUd_ckn44lh-uuKM6M,32250
|
53
53
|
fabricatio/parser.py,sha256=3vT5u5SGpzDH4WLJdMwK5CP8RqO4g1MyQUYpiDKDoEo,4528
|
54
54
|
fabricatio/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
55
|
-
fabricatio/rust.cpython-313-x86_64-linux-gnu.so,sha256=
|
56
|
-
fabricatio/rust.pyi,sha256=
|
55
|
+
fabricatio/rust.cpython-313-x86_64-linux-gnu.so,sha256=zS0XD_sVqHQLmpyDKbUjVZN-CTyRb1XVCBes2rDTOio,7911352
|
56
|
+
fabricatio/rust.pyi,sha256=D-YxXyjvX6d1Y5pkjcvv-EjQvxpkeA7qgcTaaHOtJpY,25491
|
57
57
|
fabricatio/toolboxes/__init__.py,sha256=dYm_Gd8XolSU_h4wnkA09dlaLDK146eeFz0CUgPZ8_c,380
|
58
58
|
fabricatio/toolboxes/arithmetic.py,sha256=sSTPkKI6-mb278DwQKFO9jKyzc9kCx45xNH7V6bGBpE,1307
|
59
59
|
fabricatio/toolboxes/fs.py,sha256=OQMdeokYxSNVrCZJAweJ0cYiK4k2QuEiNdIbS5IHIV8,705
|
@@ -61,4 +61,4 @@ fabricatio/utils.py,sha256=qvl4R8ThuNIIoBJuR1DGEuWYZ7jRFT_8SRx4I_FA8pU,5298
|
|
61
61
|
fabricatio/workflows/__init__.py,sha256=Lq9pFo2cudwFCrQUUNgSTr1CoU0J1Nw-HNEQN7cHLp8,50
|
62
62
|
fabricatio/workflows/articles.py,sha256=ZDV5nqUKRo1GOuuKWeSV7ZI32FYZU7WiTrD4YDuCeEo,945
|
63
63
|
fabricatio/workflows/rag.py,sha256=uOZXprD479fUhLA6sYvEM8RWcVcUZXXtP0xRbTMPdHE,509
|
64
|
-
fabricatio-0.3.
|
64
|
+
fabricatio-0.3.15.dev4.dist-info/RECORD,,
|
Binary file
|
Binary file
|
File without changes
|
File without changes
|