fabricatio 0.2.8.dev2__tar.gz → 0.2.8.dev3__tar.gz

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.
Files changed (140) hide show
  1. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/PKG-INFO +2 -1
  2. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/extract_and_inject/ask.py +1 -1
  3. fabricatio-0.2.8.dev3/examples/extract_and_inject/extract_and_inject.py +66 -0
  4. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/write_article/write_article.py +3 -3
  5. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/pyproject.toml +2 -1
  6. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/_rust.pyi +1 -1
  7. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/actions/article.py +72 -56
  8. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/actions/article_rag.py +4 -5
  9. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/actions/output.py +4 -3
  10. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/actions/rag.py +3 -3
  11. fabricatio-0.2.8.dev3/python/fabricatio/capabilities/check.py +97 -0
  12. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/capabilities/correct.py +7 -6
  13. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/capabilities/propose.py +20 -4
  14. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/capabilities/rag.py +3 -2
  15. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/capabilities/rating.py +7 -10
  16. fabricatio-0.2.8.dev3/python/fabricatio/capabilities/review.py +112 -0
  17. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/capabilities/task.py +8 -9
  18. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/config.py +2 -0
  19. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/models/action.py +6 -2
  20. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/models/extra/advanced_judge.py +7 -7
  21. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/models/extra/article_base.py +45 -8
  22. fabricatio-0.2.8.dev3/python/fabricatio/models/extra/article_essence.py +99 -0
  23. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/models/extra/article_main.py +1 -1
  24. fabricatio-0.2.8.dev3/python/fabricatio/models/extra/problem.py +120 -0
  25. fabricatio-0.2.8.dev3/python/fabricatio/models/extra/rule.py +23 -0
  26. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/models/generic.py +28 -33
  27. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/models/role.py +4 -1
  28. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/models/usages.py +8 -6
  29. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/models/utils.py +0 -46
  30. fabricatio-0.2.8.dev3/python/fabricatio/utils.py +54 -0
  31. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/src/bib_tools.rs +1 -1
  32. fabricatio-0.2.8.dev3/templates/built-in/check_string.hbs +15 -0
  33. fabricatio-0.2.8.dev3/templates.tar.gz +0 -0
  34. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/uv.lock +62 -26
  35. fabricatio-0.2.8.dev2/examples/extract_and_inject/extract_and_inject.py +0 -54
  36. fabricatio-0.2.8.dev2/python/fabricatio/capabilities/review.py +0 -281
  37. fabricatio-0.2.8.dev2/python/fabricatio/models/extra/article_essence.py +0 -268
  38. fabricatio-0.2.8.dev2/templates.tar.gz +0 -0
  39. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/.github/workflows/build-package.yaml +0 -0
  40. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/.github/workflows/ruff.yaml +0 -0
  41. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/.github/workflows/tests.yaml +0 -0
  42. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/.gitignore +0 -0
  43. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/.python-version +0 -0
  44. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/Cargo.lock +0 -0
  45. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/Cargo.toml +0 -0
  46. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/LICENSE +0 -0
  47. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/Makefile +0 -0
  48. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/README.md +0 -0
  49. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/correct/correct.py +0 -0
  50. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/correct/correct_loop.py +0 -0
  51. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/extract_and_inject/.gitignore +0 -0
  52. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/extract_and_inject/article_rag.py +0 -0
  53. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/extract_article/extract.py +0 -0
  54. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/llm_usages/llm_usage.py +0 -0
  55. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/make_a_rating/rating.py +0 -0
  56. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/make_diary/commits.json +0 -0
  57. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/make_diary/diary.py +0 -0
  58. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/minor/hello_fabricatio.py +0 -0
  59. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/minor/write_a_poem.py +0 -0
  60. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/propose_task/propose.py +0 -0
  61. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/reviewer/review.py +0 -0
  62. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/search_bibtex/.gitignore +0 -0
  63. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/search_bibtex/search.py +0 -0
  64. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/simple_chat/chat.py +0 -0
  65. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/simple_rag/simple_rag.py +0 -0
  66. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/task_handle/handle_task.py +0 -0
  67. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/write_article/.gitignore +0 -0
  68. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/write_article/article_rag.py +0 -0
  69. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/write_outline/.gitignore +0 -0
  70. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/write_outline/write_outline.py +0 -0
  71. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/examples/write_outline/write_outline_corrected.py +0 -0
  72. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/__init__.py +0 -0
  73. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/_rust_instances.py +0 -0
  74. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/capabilities/advanced_judge.py +0 -0
  75. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/core.py +0 -0
  76. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/decorators.py +0 -0
  77. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/fs/__init__.py +0 -0
  78. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/fs/curd.py +0 -0
  79. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/fs/readers.py +0 -0
  80. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/journal.py +0 -0
  81. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/models/events.py +0 -0
  82. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/models/extra/article_outline.py +0 -0
  83. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/models/extra/article_proposal.py +0 -0
  84. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/models/kwargs_types.py +0 -0
  85. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/models/task.py +0 -0
  86. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/models/tool.py +0 -0
  87. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/parser.py +0 -0
  88. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/py.typed +0 -0
  89. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/toolboxes/__init__.py +0 -0
  90. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/toolboxes/arithmetic.py +0 -0
  91. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/toolboxes/fs.py +0 -0
  92. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/workflows/articles.py +0 -0
  93. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/python/fabricatio/workflows/rag.py +0 -0
  94. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/src/hash.rs +0 -0
  95. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/src/hbs_helpers.rs +0 -0
  96. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/src/lib.rs +0 -0
  97. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/src/templates.rs +0 -0
  98. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/as_prompt.hbs +0 -0
  99. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/binary-exploitation-ctf-solver.hbs +0 -0
  100. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/claude-xml.hbs +0 -0
  101. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/clean-up-code.hbs +0 -0
  102. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/co_validation.hbs +0 -0
  103. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/correct.hbs +0 -0
  104. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/create_json_obj.hbs +0 -0
  105. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/cryptography-ctf-solver.hbs +0 -0
  106. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/dependencies.hbs +0 -0
  107. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/document-the-code.hbs +0 -0
  108. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/draft_rating_criteria.hbs +0 -0
  109. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/draft_rating_manual.hbs +0 -0
  110. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/draft_rating_weights_klee.hbs +0 -0
  111. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/draft_tool_usage_code.hbs +0 -0
  112. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/extract_criteria_from_reasons.hbs +0 -0
  113. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/extract_reasons_from_examples.hbs +0 -0
  114. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/find-security-vulnerabilities.hbs +0 -0
  115. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/fix-bugs.hbs +0 -0
  116. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/generic_string.hbs +0 -0
  117. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/improve-performance.hbs +0 -0
  118. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/liststr.hbs +0 -0
  119. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/make_choice.hbs +0 -0
  120. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/make_judgment.hbs +0 -0
  121. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/pathstr.hbs +0 -0
  122. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/rate_fine_grind.hbs +0 -0
  123. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/refactor.hbs +0 -0
  124. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/refined_query.hbs +0 -0
  125. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/retrieved_display.hbs +0 -0
  126. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/reverse-engineering-ctf-solver.hbs +0 -0
  127. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/review_string.hbs +0 -0
  128. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/task_briefing.hbs +0 -0
  129. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/web-ctf-solver.hbs +0 -0
  130. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/write-git-commit.hbs +0 -0
  131. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/write-github-pull-request.hbs +0 -0
  132. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/templates/built-in/write-github-readme.hbs +0 -0
  133. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/tests/test_config.py +0 -0
  134. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/tests/test_models/test_action.py +0 -0
  135. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/tests/test_models/test_advanced.py +0 -0
  136. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/tests/test_models/test_generic.py +0 -0
  137. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/tests/test_models/test_role.py +0 -0
  138. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/tests/test_models/test_task.py +0 -0
  139. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/tests/test_models/test_tool.py +0 -0
  140. {fabricatio-0.2.8.dev2 → fabricatio-0.2.8.dev3}/tests/test_models/test_usages.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fabricatio
3
- Version: 0.2.8.dev2
3
+ Version: 0.2.8.dev3
4
4
  Classifier: License :: OSI Approved :: MIT License
5
5
  Classifier: Programming Language :: Rust
6
6
  Classifier: Programming Language :: Python :: 3.12
@@ -23,6 +23,7 @@ Requires-Dist: pymitter>=1.0.0
23
23
  Requires-Dist: questionary>=2.1.0
24
24
  Requires-Dist: regex>=2024.11.6
25
25
  Requires-Dist: rich>=13.9.4
26
+ Requires-Dist: rtoml>=0.12.0
26
27
  Requires-Dist: pymilvus>=2.5.4 ; extra == 'rag'
27
28
  Requires-Dist: fabricatio[calc,plot,rag] ; extra == 'full'
28
29
  Requires-Dist: sympy>=1.13.3 ; extra == 'calc'
@@ -4,7 +4,7 @@ import asyncio
4
4
 
5
5
  from fabricatio import RAG, Action, Role, Task, WorkFlow, logger
6
6
  from fabricatio.models.events import Event
7
- from fabricatio.models.utils import ok
7
+ from fabricatio.utils import ok
8
8
  from questionary import text
9
9
 
10
10
 
@@ -0,0 +1,66 @@
1
+ """Example of proposing a task to a role."""
2
+
3
+ import asyncio
4
+ from typing import Optional
5
+
6
+ from fabricatio import BibManager, Event, Role, Task, WorkFlow, logger
7
+ from fabricatio.actions.article import ExtractArticleEssence, FixArticleEssence
8
+ from fabricatio.actions.output import PersistentAll
9
+ from fabricatio.actions.rag import InjectToDB
10
+ from fabricatio.fs import safe_text_read
11
+ from fabricatio.fs.curd import gather_files
12
+ from litellm.utils import token_counter
13
+
14
+ MAX_TOKEN = 64000
15
+
16
+
17
+ def _reader(path:str)->Optional[str]:
18
+ string=safe_text_read(path)
19
+ string=string.split("References\n")[0]
20
+ string=string.split("参考文献\n")[0]
21
+ if (leng:=token_counter(text=string))> MAX_TOKEN:
22
+ logger.warning(f'{path} is too long, got {leng} tokens, skip.')
23
+ return None
24
+ logger.info(f'Read {path} get {leng} tokens.')
25
+ return string
26
+ async def main() -> None:
27
+ """Main function."""
28
+ Role(
29
+ name="Researcher",
30
+ description="Extract article essence",
31
+ llm_model="openai/deepseek-v3-250324",
32
+ registry={
33
+ Event.quick_instantiate("article"): WorkFlow(
34
+ name="extract",
35
+ steps=(
36
+ ExtractArticleEssence(output_key="article_essence"),
37
+ FixArticleEssence(output_key="to_inject"),
38
+ PersistentAll,
39
+ InjectToDB(output_key="task_output"),
40
+ ),
41
+ ).update_init_context(
42
+ override_inject=True,
43
+ collection_name="article_essence_0324",
44
+ persist_dir="output_0324",
45
+ bib_mgr=BibManager("ref.bib"),
46
+ reader=_reader
47
+ )
48
+ },
49
+ )
50
+
51
+ task: Task[str] = Task(
52
+ name="Extract Article Essence",
53
+ description="Extract the essence of the article from the files in './bpdf_out'",
54
+ dependencies=gather_files("bpdf_out", "md"),
55
+ )
56
+
57
+ col_name = await task.delegate("article")
58
+
59
+ if col_name is None:
60
+ logger.error("No essence found")
61
+ return
62
+ logger.success(f"Injected to collection: {col_name}")
63
+
64
+
65
+ if __name__ == "__main__":
66
+ asyncio.run(main())
@@ -25,9 +25,9 @@ async def main() -> None:
25
25
  description="Write an outline for an article in typst format.",
26
26
  llm_top_p=0.8,
27
27
  llm_temperature=1.15,
28
- llm_model="openai/qwen-max",
28
+ llm_model="openai/deepseek-v3-250324",
29
29
  llm_rpm=1000,
30
- llm_tpm=10000000,
30
+ llm_tpm=1000000,
31
31
  llm_max_tokens=8190,
32
32
  registry={
33
33
  Event.quick_instantiate(ns := "article"): WorkFlow(
@@ -35,7 +35,7 @@ async def main() -> None:
35
35
  description="Generate an outline for an article. dump the outline to the given path. in typst format.",
36
36
  steps=(
37
37
  GenerateArticleProposal(llm_temperature=1.18),
38
- GenerateInitialOutline(output_key="article_outline",llm_temperature=1.21, llm_top_p=0.3),
38
+ GenerateInitialOutline(output_key="article_outline",llm_temperature=1.21, llm_top_p=0.5),
39
39
  FixIntrospectedErrors(output_key="article_outline"),
40
40
  FixIllegalReferences(output_key="article_outline"),
41
41
  TweakOutlineBackwardRef(output_key="article_outline"),
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "fabricatio"
3
- version = "0.2.8-dev2"
3
+ version = "0.2.8-dev3"
4
4
  description = "A LLM multi-agent framework."
5
5
  readme = "README.md"
6
6
  license = { file = "LICENSE" }
@@ -42,6 +42,7 @@ dependencies = [
42
42
  "questionary>=2.1.0",
43
43
  "regex>=2024.11.6",
44
44
  "rich>=13.9.4",
45
+ "rtoml>=0.12.0",
45
46
  ]
46
47
 
47
48
  [project.urls]
@@ -171,4 +171,4 @@ class BibManager:
171
171
 
172
172
  Returns:
173
173
  Field value if found, None otherwise
174
- """
174
+ """
@@ -15,7 +15,8 @@ from fabricatio.models.extra.article_main import Article
15
15
  from fabricatio.models.extra.article_outline import ArticleOutline
16
16
  from fabricatio.models.extra.article_proposal import ArticleProposal
17
17
  from fabricatio.models.task import Task
18
- from fabricatio.models.utils import ok
18
+ from fabricatio.utils import ok
19
+ from more_itertools import filter_map
19
20
 
20
21
 
21
22
  class ExtractArticleEssence(Action):
@@ -32,36 +33,62 @@ class ExtractArticleEssence(Action):
32
33
  async def _execute(
33
34
  self,
34
35
  task_input: Task,
35
- reader: Callable[[str], str] = lambda p: Path(p).read_text(encoding="utf-8"),
36
+ reader: Callable[[str], Optional[str]] = lambda p: Path(p).read_text(encoding="utf-8"),
36
37
  **_,
37
- ) -> Optional[List[ArticleEssence]]:
38
+ ) -> List[ArticleEssence]:
38
39
  if not task_input.dependencies:
39
40
  logger.info(err := "Task not approved, since no dependencies are provided.")
40
41
  raise RuntimeError(err)
41
-
42
+ logger.info(f"Extracting article essence from {len(task_input.dependencies)} files.")
42
43
  # trim the references
43
- contents = ["References".join(c.split("References")[:-1]) for c in map(reader, task_input.dependencies)]
44
- return await self.propose(ArticleEssence, contents, **self.prepend_sys_msg())
44
+ contents = list(filter_map(reader, task_input.dependencies))
45
+ logger.info(f"Read {len(task_input.dependencies)} to get {len(contents)} contents.")
46
+
47
+ out = []
48
+
49
+ for ess in await self.propose(
50
+ ArticleEssence,
51
+ [
52
+ f"{c}\n\n\nBased the provided academic article above, you need to extract the essence from it."
53
+ for c in contents
54
+ ],
55
+ ):
56
+ if ess is None:
57
+ logger.warning("Could not extract article essence")
58
+ else:
59
+ out.append(ess)
60
+ logger.info(f"Extracted {len(out)} article essence from {len(task_input.dependencies)} files.")
61
+ return out
45
62
 
46
63
 
47
64
  class FixArticleEssence(Action):
48
65
  """Fix the article essence based on the bibtex key."""
49
66
 
67
+ output_key: str = "fixed_article_essence"
68
+ """The key of the output data."""
69
+
50
70
  async def _execute(
51
71
  self,
52
72
  bib_mgr: BibManager,
53
73
  article_essence: List[ArticleEssence],
54
74
  **_,
55
- ) -> None:
75
+ ) -> List[ArticleEssence]:
76
+ out = []
77
+ count = 0
56
78
  for a in article_essence:
57
79
  if key := (bib_mgr.get_cite_key(a.title) or bib_mgr.get_cite_key_fuzzy(a.title)):
58
80
  a.title = bib_mgr.get_title_by_key(key) or a.title
59
81
  a.authors = bib_mgr.get_author_by_key(key) or a.authors
60
82
  a.publication_year = bib_mgr.get_year_by_key(key) or a.publication_year
61
83
  a.bibtex_cite_key = key
62
- logger.info(f'Updated {a.title} with {key}')
84
+ logger.info(f"Updated {a.title} with {key}")
85
+ out.append(a)
63
86
  else:
64
87
  logger.warning(f"No key found for {a.title}")
88
+ count += 1
89
+ if count:
90
+ logger.warning(f"{count} articles have no key")
91
+ return out
65
92
 
66
93
 
67
94
  class GenerateArticleProposal(Action):
@@ -97,7 +124,6 @@ class GenerateArticleProposal(Action):
97
124
  )
98
125
  )
99
126
  ),
100
- **self.prepend_sys_msg(),
101
127
  ),
102
128
  "Could not generate the proposal.",
103
129
  ).update_ref(briefing)
@@ -122,7 +148,6 @@ class GenerateInitialOutline(Action):
122
148
  await self.propose(
123
149
  ArticleOutline,
124
150
  article_proposal.as_prompt(),
125
- **self.prepend_sys_msg(),
126
151
  ),
127
152
  "Could not generate the initial outline.",
128
153
  ).update_ref(article_proposal)
@@ -190,90 +215,81 @@ class FixIllegalReferences(Action):
190
215
  "Could not generate the rating manual.",
191
216
  )
192
217
 
193
- while pack := article_outline.find_illegal_ref():
194
- ref, err = ok(pack)
218
+ while pack := article_outline.find_illegal_ref(gather_identical=True):
219
+ refs, err = ok(pack)
195
220
  logger.warning(f"Found illegal referring error: {err}")
196
- ok(
197
- await self.correct_obj_inplace(
198
- ref,
221
+ corrected_ref = ok(
222
+ await self.correct_obj(
223
+ refs[0], # pyright: ignore [reportIndexIssue]
199
224
  reference=f"# Original Article Outline\n{article_outline.display()}\n# Error Need to be fixed\n{err}",
200
225
  topic=ref_topic,
201
226
  rating_manual=ref_manual,
202
227
  supervisor_check=supervisor_check,
203
228
  )
204
229
  )
230
+ for ref in refs:
231
+ ref.update_from(corrected_ref) # pyright: ignore [reportAttributeAccessIssue]
232
+
205
233
  return article_outline.update_ref(article_outline)
206
234
 
207
235
 
208
- class TweakOutlineBackwardRef(Action, AdvancedJudge):
209
- """Tweak the backward references in the article outline.
236
+ class TweakOutlineForwardRef(Action, AdvancedJudge):
237
+ """Tweak the forward references in the article outline.
210
238
 
211
- Ensures that the prerequisites of the current chapter are correctly referenced in the `depend_on` field.
239
+ Ensures that the conclusions of the current chapter effectively support the analysis of subsequent chapters.
212
240
  """
213
241
 
214
- output_key: str = "article_outline_bw_ref_checked"
242
+ output_key: str = "article_outline_fw_ref_checked"
215
243
 
216
244
  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.",
245
+ return await self._inner(
246
+ article_outline,
247
+ supervisor_check,
248
+ topic="Ensure conclusions support the analysis of subsequent chapters, sections or subsections.",
249
+ field_name="support_to",
222
250
  )
223
251
 
252
+ async def _inner(
253
+ self, article_outline: ArticleOutline, supervisor_check: bool, topic: str, field_name: str
254
+ ) -> ArticleOutline:
255
+ tweak_support_to_manual = ok(
256
+ await self.draft_rating_manual(topic),
257
+ "Could not generate the rating manual.",
258
+ )
224
259
  for a in article_outline.iter_dfs():
225
260
  if await self.evidently_judge(
226
261
  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?"
262
+ f"Does the `{a.__class__.__name__}`'s `{field_name}` field need to be extended or tweaked?"
228
263
  ):
229
264
  patch = ArticleRefPatch.default()
230
- patch.tweaked = a.depend_on
265
+ patch.tweaked = getattr(a, field_name)
231
266
 
232
267
  await self.correct_obj_inplace(
233
268
  patch,
234
269
  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,
270
+ reference=f"{article_outline.as_prompt()}\nThe Article component whose `{field_name}` field needs to be extended or tweaked",
271
+ rating_manual=tweak_support_to_manual,
237
272
  supervisor_check=supervisor_check,
238
273
  )
239
-
240
274
  return article_outline
241
275
 
242
276
 
243
- class TweakOutlineForwardRef(Action, AdvancedJudge):
244
- """Tweak the forward references in the article outline.
277
+ class TweakOutlineBackwardRef(TweakOutlineForwardRef):
278
+ """Tweak the backward references in the article outline.
245
279
 
246
- Ensures that the conclusions of the current chapter effectively support the analysis of subsequent chapters.
280
+ Ensures that the prerequisites of the current chapter are correctly referenced in the `depend_on` field.
247
281
  """
248
282
 
249
- output_key: str = "article_outline_fw_ref_checked"
283
+ output_key: str = "article_outline_bw_ref_checked"
250
284
 
251
285
  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.",
286
+ return await self._inner(
287
+ article_outline,
288
+ supervisor_check,
289
+ topic="Ensure the dependencies of the current chapter are neither abused nor missing.",
290
+ field_name="depend_on",
257
291
  )
258
292
 
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
276
-
277
293
 
278
294
  class GenerateArticle(Action):
279
295
  """Generate the article based on the outline."""
@@ -6,7 +6,7 @@ from typing import Dict, Optional
6
6
  from fabricatio.capabilities.rag import RAG
7
7
  from fabricatio.models.action import Action
8
8
  from fabricatio.models.extra.article_main import Article, ArticleParagraphPatch, ArticleSubsection
9
- from fabricatio.models.utils import ok
9
+ from fabricatio.utils import ok
10
10
 
11
11
 
12
12
  class TweakArticleRAG(Action, RAG):
@@ -25,7 +25,8 @@ class TweakArticleRAG(Action, RAG):
25
25
  "Single author: 'Author1 (YYYY)'"
26
26
  "Multiple citations: 'Author1 (YYYY), Author2 (YYYY)'"
27
27
  "Prioritize formulas from reference highlights."
28
- "Specify authors/years only - no numeric citations"
28
+ "Specify authors/years only."
29
+ "You can create numeric citation numbers for article whose `bibtex_cite_key` is 'wangWind2024' by using notation like `#cite(<wangWind2024>)`."
29
30
  "Paragraphs must exceed 2-3 sentences",
30
31
  supervisor_check: bool = False,
31
32
  parallel: bool = False,
@@ -41,9 +42,7 @@ class TweakArticleRAG(Action, RAG):
41
42
  criteria_count=13,
42
43
  )
43
44
 
44
- tweak_manual = ok(
45
- await self.draft_rating_manual(topic, criteria=criteria, co_extractor={"model": "openai/qwen-max"})
46
- )
45
+ tweak_manual = ok(await self.draft_rating_manual(topic, criteria=criteria))
47
46
  self.view(collection_name)
48
47
 
49
48
  if parallel:
@@ -7,7 +7,7 @@ from fabricatio.journal import logger
7
7
  from fabricatio.models.action import Action
8
8
  from fabricatio.models.generic import FinalizedDumpAble, PersistentAble
9
9
  from fabricatio.models.task import Task
10
- from fabricatio.models.utils import ok
10
+ from fabricatio.utils import ok
11
11
 
12
12
 
13
13
  class DumpFinalizedOutput(Action):
@@ -67,17 +67,18 @@ class PersistentAll(Action):
67
67
 
68
68
  for k, v in cxt.items():
69
69
  final_dir = persist_dir.joinpath(k)
70
- final_dir.mkdir(parents=True, exist_ok=True)
71
70
  if isinstance(v, PersistentAble):
71
+ final_dir.mkdir(parents=True, exist_ok=True)
72
72
  v.persist(final_dir)
73
73
  count += 1
74
74
  if isinstance(v, Iterable) and any(
75
75
  persistent_ables := (pers for pers in v if isinstance(pers, PersistentAble))
76
76
  ):
77
+ final_dir.mkdir(parents=True, exist_ok=True)
77
78
  for per in persistent_ables:
78
79
  per.persist(final_dir)
79
80
  count += 1
80
-
81
+ logger.info(f"Persisted {count} objects to {persist_dir}")
81
82
  return count
82
83
 
83
84
 
@@ -5,7 +5,7 @@ from typing import List, Optional
5
5
  from fabricatio.capabilities.rag import RAG
6
6
  from fabricatio.journal import logger
7
7
  from fabricatio.models.action import Action
8
- from fabricatio.models.generic import PrepareVectorization
8
+ from fabricatio.models.generic import Vectorizable
9
9
  from fabricatio.models.task import Task
10
10
  from questionary import text
11
11
 
@@ -15,7 +15,7 @@ class InjectToDB(Action, RAG):
15
15
 
16
16
  output_key: str = "collection_name"
17
17
 
18
- async def _execute[T: PrepareVectorization](
18
+ async def _execute[T: Vectorizable](
19
19
  self, to_inject: Optional[T] | List[Optional[T]], collection_name: str = "my_collection",override_inject:bool=False, **_
20
20
  ) -> Optional[str]:
21
21
  if not isinstance(to_inject, list):
@@ -27,7 +27,7 @@ class InjectToDB(Action, RAG):
27
27
  [
28
28
  t.prepare_vectorization(self.embedding_max_sequence_length)
29
29
  for t in to_inject
30
- if isinstance(t, PrepareVectorization)
30
+ if isinstance(t, Vectorizable)
31
31
  ],
32
32
  )
33
33
 
@@ -0,0 +1,97 @@
1
+ """A class that provides the capability to check strings and objects against rules and guidelines."""
2
+ from typing import Optional, Unpack
3
+
4
+ from fabricatio import TEMPLATE_MANAGER
5
+ from fabricatio.capabilities.advanced_judge import AdvancedJudge
6
+ from fabricatio.capabilities.propose import Propose
7
+ from fabricatio.config import configs
8
+ from fabricatio.models.extra.problem import Improvement
9
+ from fabricatio.models.extra.rule import Rule, RuleSet
10
+ from fabricatio.models.generic import Display, WithBriefing
11
+ from fabricatio.models.kwargs_types import ValidateKwargs
12
+ from fabricatio.utils import override_kwargs
13
+
14
+
15
+ class Check(AdvancedJudge, Propose):
16
+ """Class that provides the capability to validate strings/objects against predefined rules and guidelines."""
17
+
18
+ async def draft_ruleset(
19
+ self, ruleset_requirement: str, **kwargs: Unpack[ValidateKwargs[RuleSet]]
20
+ ) -> Optional[RuleSet]:
21
+ """Generate a rule set based on specified requirements.
22
+
23
+ Args:
24
+ ruleset_requirement (str): Description of desired rule set characteristics
25
+ **kwargs: Validation configuration parameters
26
+
27
+ Returns:
28
+ Optional[RuleSet]: Generated rule set if successful
29
+ """
30
+ return await self.propose(RuleSet, ruleset_requirement, **kwargs)
31
+
32
+ async def draft_rule(self, rule_requirement: str, **kwargs: Unpack[ValidateKwargs[Rule]]) -> Optional[Rule]:
33
+ """Create a specific rule based on given specifications.
34
+
35
+ Args:
36
+ rule_requirement (str): Detailed rule description requirements
37
+ **kwargs: Validation configuration parameters
38
+
39
+ Returns:
40
+ Optional[Rule]: Generated rule instance if successful
41
+ """
42
+ return await self.propose(Rule, rule_requirement, **kwargs)
43
+
44
+ async def check_string(
45
+ self,
46
+ input_text: str,
47
+ rule: Rule,
48
+ **kwargs: Unpack[ValidateKwargs[Improvement]],
49
+ ) -> Optional[Improvement]:
50
+ """Evaluate text against a specific rule.
51
+
52
+ Args:
53
+ input_text (str): Text content to be evaluated
54
+ rule (Rule): Rule instance used for validation
55
+ **kwargs: Validation configuration parameters
56
+
57
+ Returns:
58
+ Optional[Improvement]: Suggested improvement if violations found, else None
59
+ """
60
+ if judge := await self.evidently_judge(
61
+ f"# Content to exam\n{input_text}\n\n# Rule Must to follow\n{rule.display()}\nDoes `Content to exam` provided above violate the `Rule Must to follow` provided above?",
62
+ **override_kwargs(kwargs, default=None),
63
+ ):
64
+ return await self.propose(
65
+ Improvement,
66
+ TEMPLATE_MANAGER.render_template(
67
+ configs.templates.check_string_template,
68
+ {"to_check": input_text, "rule": rule, "judge": judge.display()},
69
+ ),
70
+ **kwargs,
71
+ )
72
+ return None
73
+
74
+ async def check_obj[M: (Display, WithBriefing)](
75
+ self,
76
+ obj: M,
77
+ rule: Rule,
78
+ **kwargs: Unpack[ValidateKwargs[Improvement]],
79
+ ) -> Optional[Improvement]:
80
+ """Validate an object against specified rule.
81
+
82
+ Args:
83
+ obj (M): Object implementing Display or WithBriefing interface
84
+ rule (Rule): Validation rule to apply
85
+ **kwargs: Validation configuration parameters
86
+
87
+ Returns:
88
+ Optional[Improvement]: Improvement suggestion if issues detected
89
+ """
90
+ if isinstance(obj, Display):
91
+ input_text = obj.display()
92
+ elif isinstance(obj, WithBriefing):
93
+ input_text = obj.briefing
94
+ else:
95
+ raise TypeError("obj must be either Display or WithBriefing")
96
+
97
+ return await self.check_string(input_text, rule, **kwargs)
@@ -8,8 +8,9 @@ based on predefined criteria and templates.
8
8
  from typing import Optional, Unpack, cast
9
9
 
10
10
  from fabricatio._rust_instances import TEMPLATE_MANAGER
11
- from fabricatio.capabilities.review import Review, ReviewResult
11
+ from fabricatio.capabilities.review import Review
12
12
  from fabricatio.config import configs
13
+ from fabricatio.models.extra.problem import Improvement
13
14
  from fabricatio.models.generic import CensoredAble, Display, ProposedAble, ProposedUpdateAble, WithBriefing
14
15
  from fabricatio.models.kwargs_types import CensoredCorrectKwargs, CorrectKwargs, ReviewKwargs
15
16
  from fabricatio.models.task import Task
@@ -31,7 +32,7 @@ class Correct(Review):
31
32
  obj: M,
32
33
  reference: str = "",
33
34
  supervisor_check: bool = True,
34
- **kwargs: Unpack[ReviewKwargs[ReviewResult[str]]],
35
+ **kwargs: Unpack[ReviewKwargs[Improvement]],
35
36
  ) -> Optional[M]:
36
37
  """Review and correct an object based on defined criteria and templates.
37
38
 
@@ -71,7 +72,7 @@ class Correct(Review):
71
72
  )
72
73
 
73
74
  async def correct_string(
74
- self, input_text: str, supervisor_check: bool = True, **kwargs: Unpack[ReviewKwargs[ReviewResult[str]]]
75
+ self, input_text: str, supervisor_check: bool = True, **kwargs: Unpack[ReviewKwargs[Improvement]]
75
76
  ) -> Optional[str]:
76
77
  """Review and correct a string based on defined criteria and templates.
77
78
 
@@ -100,7 +101,7 @@ class Correct(Review):
100
101
  )
101
102
 
102
103
  async def correct_task[T](
103
- self, task: Task[T], **kwargs: Unpack[CorrectKwargs[ReviewResult[str]]]
104
+ self, task: Task[T], **kwargs: Unpack[CorrectKwargs[Improvement]]
104
105
  ) -> Optional[Task[T]]:
105
106
  """Review and correct a task object based on defined criteria.
106
107
 
@@ -117,7 +118,7 @@ class Correct(Review):
117
118
  return await self.correct_obj(task, **kwargs)
118
119
 
119
120
  async def censor_obj[M: CensoredAble](
120
- self, obj: M, **kwargs: Unpack[CensoredCorrectKwargs[ReviewResult[str]]]
121
+ self, obj: M, **kwargs: Unpack[CensoredCorrectKwargs[Improvement]]
121
122
  ) -> M:
122
123
  """Censor and correct an object based on defined criteria and templates.
123
124
 
@@ -147,7 +148,7 @@ class Correct(Review):
147
148
  return modified_obj or last_modified_obj
148
149
 
149
150
  async def correct_obj_inplace[M: ProposedUpdateAble](
150
- self, obj: M, **kwargs: Unpack[CorrectKwargs[ReviewResult[str]]]
151
+ self, obj: M, **kwargs: Unpack[CorrectKwargs[Improvement]]
151
152
  ) -> Optional[M]:
152
153
  """Correct an object in place based on defined criteria and templates.
153
154
 
@@ -10,28 +10,43 @@ from fabricatio.models.usages import LLMUsage
10
10
  class Propose(LLMUsage):
11
11
  """A class that proposes an Obj based on a prompt."""
12
12
 
13
+ @overload
14
+ async def propose[M: ProposedAble](
15
+ self,
16
+ cls: Type[M],
17
+ prompt: List[str],
18
+ **kwargs: Unpack[ValidateKwargs[None]],
19
+ ) -> List[Optional[M]]: ...
20
+
13
21
  @overload
14
22
  async def propose[M: ProposedAble](
15
23
  self,
16
24
  cls: Type[M],
17
25
  prompt: List[str],
18
26
  **kwargs: Unpack[ValidateKwargs[M]],
19
- ) -> Optional[List[M]]: ...
27
+ ) -> List[M]: ...
20
28
 
21
29
  @overload
22
30
  async def propose[M: ProposedAble](
23
31
  self,
24
32
  cls: Type[M],
25
33
  prompt: str,
26
- **kwargs: Unpack[ValidateKwargs[M]],
34
+ **kwargs: Unpack[ValidateKwargs[None]],
27
35
  ) -> Optional[M]: ...
36
+ @overload
37
+ async def propose[M: ProposedAble](
38
+ self,
39
+ cls: Type[M],
40
+ prompt: str,
41
+ **kwargs: Unpack[ValidateKwargs[M]],
42
+ ) -> M: ...
28
43
 
29
44
  async def propose[M: ProposedAble](
30
45
  self,
31
46
  cls: Type[M],
32
47
  prompt: List[str] | str,
33
- **kwargs: Unpack[ValidateKwargs[M]],
34
- ) -> Optional[List[M] | M]:
48
+ **kwargs: Unpack[ValidateKwargs[Optional[M]]],
49
+ ) -> Optional[M] | List[Optional[M]] | M | List[M]:
35
50
  """Asynchronously proposes a task based on a given prompt and parameters.
36
51
 
37
52
  Parameters:
@@ -47,3 +62,4 @@ class Propose(LLMUsage):
47
62
  validator=cls.instantiate_from_string,
48
63
  **kwargs,
49
64
  )
65
+